K&R复习1

问题:如何将连续的空白符合并成一个空白符输出?

分析: 可以设定一个变量进行控制.假设设定变量bSpace.当它为1时候,代表出现空白字符,当出现非空白字符并且bSpace=1时,则输出一个空白字符,用来代替之前所有的空白字符的输出.

代码:

#include <stdio.h>
int main()
{
    int c;
    int bSpace = 0;
    while ((c = getchar()) != EOF) {
        if (' ' == c) {
            bSpace = 1;
        } else {
            if (bSpace) {
                putchar(' ');
                bSpace = 0;
            }
            putchar(c);
        }
    }
}

同样适用于:

  1. 统计单词个数.


问题:如何打印一个单词的水平直方图

分析: 可以设定一个变量统计单词字符的个数.遍历整个字符串,遇到单词结束则putchar出此单词和由单词字符个数产生的*号.

代码:

#include <stdio.h>
int main()
{
    int c;
    int nCount = 0;
    while ((c = getchar()) != EOF) {
        if ((' ' != c) && ('\t' != c) && ('\n' != c)) {
            putchar(c);
            nCount++;
        } else {
            if (0 == nCount) {
                continue;
            }
            putchar(':');
            while (--nCount >= 0) {
                 putchar('*');
            }
            putchar('\n');
            nCount = 0;
        }
    }
}


问题:如何打印一个单词的垂直直方图

分析:

1. 我们需要三个数组进行存储.一个用于存储代表单词长度,一个用于存储单词的索引,一个用于存储单词(一维数组,以空格进行单词的区分).

2. 我们需要进行单词的判断,并且舍弃空白符.

代码:

#include <stdio.h>
#define SIZE 100
#define row 10
int main()
{
    int c;
    int i = 0, j = 0, k = 0, m = 0;
    int nSpace = 0;
    int isStar = 0;
    char    word[SIZE];
    int    index[row];//存储单词的起始索引
    int     len[row];//存储每个单词的长度
    int maxlen = 0;  //单词的最大长度
    int wordlen = 0;//所有单词的长度
    int wordnum = 0;//单词的个数
    index[0] = 0;
    while ((c = getchar()) != EOF) {
        if (' ' == c || '\t' == c || '\n' == c) {
            if (0 != j) {
                len[m++] = j;
                if (j > maxlen) {
                    maxlen = j;
                }
                j = 0;
            }
            nSpace = 1;
        } else {
            if (1 == nSpace) {
                nSpace = 0;
                word[i++] = ' ';
                index[++k] = i;
            }
            word[i++] = c;
            j++;
        }
    }
    word[i] = '\0';
    wordlen = i;
    wordnum = k + 1;
    printf("%d\t%d\n", wordlen, wordnum);
    for (i = 0; i < wordnum; i++) {
         printf("%d ", index[i]);
    }
    for (i = 0; i < wordnum; i++) {
         printf("%d ", len[i]);
    }
    putchar('\n');
    for (i = 0; i < maxlen; i++) {
        for (j = 0; j < wordlen; j++) {
            for (k = 0; k < wordnum; k++) {
                if (j == index[k] && len[k] >= maxlen - i) {
                    putchar('*');
                    isStar = 1;
                }
            }
            if (0 == isStar) {
                 putchar(' ');
            } else {
                isStar = 0;
            }
        }
        putchar('\n');
    }
    printf("%s\n", word);
    return 0;
}

效果图:

bogon:~ lgt$ ./a.out
hello world i love this
world and i love
40	9
0 6 12 14 19 24 30 34 36 5 5 1 4 4 5 3 1 4
*     *                 *
*     *       *    *    *           *
*     *       *    *    *     *     *
*     *       *    *    *     *     *
*     *     * *    *    *     *   * *
hello world i love this world and i love


问题:如何打印最长的一句话

分析: 

1. 我们需要用链表来保证可输入在内存允许情况下,任意长度的一句话

2. 由于链表是动态生成的,则将两个链表进行长度比较时,要动态释放长度较短的那个链表.

3. 输入字符串hello world,我们生成的链表为d->l->r->o->w-> ->o->l->l->e->h.之所以倒序,是因为往链表的尾部插入要么需要遍历链表,要么需要双向链表.

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct NODE{
    int             value;
    struct NODE     *next;
} Node;

void printNode( Node *node )
{
    while ( node ){
        printf("%c", node->value);
        node = node->next;
    }
    printf("\n");
}

int main(void)
{
    int     count = 0;      //当前行的长度
    int     maxLine = 0;    //最大行的长度
    int     ch;
    Node    *node1 = NULL;  //这里node1一定要初始化(PS:之前我经常忘记,因为用的是静态的节点,导致自动初始化)
    Node    *tempNode = NULL;
    Node    *resultNode = NULL;
    while ( ( ch = getchar() ) != EOF ){
        if ( ch != '\n' ){
            count++;
            tempNode = malloc( sizeof( Node ) );
            tempNode->value = ch;
            tempNode->next = node1;
            node1 = tempNode;
        }
        else if( count > maxLine ){
            printNode(node1);
            printf("-----\n");
            Node *newNode;
            Node *deleteNode;
            maxLine = count;
            count = 0;
            while ( resultNode ){
                deleteNode = resultNode;
                resultNode = resultNode->next;
                free( deleteNode );             //这里进行节点的删除的时候,一定要建立一个临时的变量进行存储节点,对临时的变量进行删除
            }
            while ( node1 ){
                newNode = malloc( sizeof( Node ) );
                newNode->value = node1->value;
                newNode->next = resultNode;
                resultNode = newNode;
                node1 = node1->next;
            }
        }
    }

    printNode( resultNode );

    return 0;
}


问题:如何拆分一句话(将一句话拆分为若干行,每行有若干个单词组成,每行的长度不可超过10个字符)

1. 将一句话存入一个数组,进行逻辑判断,如果当前单词的长度+之前所有单词的长度 > 10,则在它们之间插入换行符\n.

备注: 1.需要考虑多个空白字符.不可将多个空白字符合并成一个空白字符.

2. 单词是不可分割的.

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXLINE 128
#define LENGTH 10

void showMulLine(char *line)
{
    char        arr[MAXLINE][MAXLINE] = {'\0'};
    int         i = 0;
    int         j = 0;
    int         isEnd = 0;
    int         size;       //数组的个数
    int         len;
    int         index = 0;
    
    //将输入的一行数据分割成以空白字符分割的字符串数组:hello   world   i  love ,则数组中存储["hello   ", "world   ", "i  ", "love "];
    while (*line) {
        if ((' ' == *line || '\t' == *line || '\n' == *line)) {
            arr[i][j++] = *line;
            line++;
            isEnd =1;
            continue;
        }
        if (' ' != *line && '\t' != *line && '\n' != *line) {
            if (isEnd) {
                j = 0;
                i++;
                arr[i][j++] = *line;
                isEnd = 0;
            } else {
                arr[i][j++] = *line;
            }
            line++;
        }
    }
    
    size = i;
    len = 0;
    index = 0;
    //以LENGTH为长度进行分割操作
    for (i = 0; i <= size; i++) {
        len += strlen(arr[i]);
        if (len < LENGTH) {
            index++;
            printf("%s", arr[i]);
        }
        else {
            if (index == 0) {
                printf("%s", arr[i]);
            }
            else {
                i--;
            }
            printf("\n");
            len = 0;
        }
    }
}

int main(void)
{
    char arr[ MAXLINE ];
    while ( fgets( arr, MAXLINE, stdin ) != NULL ){
        showMulLine( arr );
    }
    
    return 0;
}






你可能感兴趣的:(k&r)