数据结构学习(三)

来源:互联网 发布:软件打不开闪退怎么办 编辑:程序博客网 时间:2024/05/16 08:29

数据结构学习(三)

目录:

编程专练:

1、字符串中子串替换:

2、反序输出字符:

3、求手机键盘输入字母方式所需时间:

4、一个整数拆分成2的幂的和:

5、求n的阶乘:


1、输入一个字符串,以回车结束(字符串长度<=100)。该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写。现需要将其中的某个单词替换成另一个单词,并输出替换之后的字符串。

########## 输入描述 ##########

多组数据。每组数据输入包括3行,

第1行是包含多个单词的字符串 s,

第2行是待替换的单词a,(长度<=100)

第3行是a将被替换的单词b。(长度<=100)

s, a, b 最前面和最后面都没有空格.

########## 输出描述 ##########

每个测试数据输出只有 1 行,

将s中所有单词a替换成b之后的字符串。

#include <stdio.h>#include <string.h>#include <stdlib.h>void strReplace(char* str, char* beChangedStr, char* changeToStr){    //从字符串的首字符开始遍历,直到字符串结束符为止while(*str != '\0'){//首字母匹配成功if(*str == *beChangedStr){//待替换的单词在字符串中匹配成功if(strncmp(str, beChangedStr, strlen(beChangedStr)) == 0){int i = strlen(beChangedStr);//计算待替换单词长度char* q = str + i;//q指针指向剩余字符串的首地址char* p = q;//p指针也指向剩余字符串的首地址char* m = changeToStr;//m指针指向被替换的单词首地址int leftLength = 0;//定义剩余的字符串长度while(*q++ != '\0'){leftLength++;}char* temp = (char *)malloc(sizeof(char) * leftLength);//临时开辟一段内存保存剩余长度的字符串,防止内存覆盖for(int k = 0; k < leftLength; k++){*(temp + k) = *(p + k);}*(temp + leftLength) = '\0';while(*m != '\0'){*str++ = *m++;//进行单词的替换}p = str;//p指向替换后的字符串的首地址char* pTemp = temp;//pTemp指向剩余长度的字符串的首地址while(*pTemp != '\0'){*p++ = *pTemp++;}free(temp);*p = '\0';//添加终止符}//没有匹配成功,则继续遍历else{str++;}}//没有匹配成功,则继续遍历else{str++;}}}int main(){char str[220];char beChangedStr[110];char changeToStr[110];gets(str);gets(beChangedStr);gets(changeToStr);strReplace(str, beChangedStr, changeToStr);printf("%s\n",str);}
运行结果:

图1.1 运行结果

2、输入任意4个字符(如:abcd), 并按反序输出(如:dcba)。

########## 输入描述 ##########

题目可能包含多组用例,每组用例占一行,包含4个任意的字符。

########## 输出描述 ##########

对于每组输入,请输出一行反序后的字符串。

#include <stdio.h>#define LENGTH 4int main(){    char c[4];    while( gets(c) != NULL){        for(int i = LENGTH - 1; i  >= 0 ; i--){           printf("%c", c[i]);        }        printf("\n");    }    return 0;}
运行结果:

图2.1 运行结果


3、按照手机键盘输入字母的方式,计算所花费的时间 如:a,b,c都在“1”键上,输入a只需要按一次,输入c需要连续按三次。 如果连续两个字符不在同一个按键上,则可直接按,如:ad需要按两下,kz需要按6下 如果连续两字符在同一个按键上,则两个按键之间需要等一段时间,如ac,在按了a之后,需要等一会儿才能按c。 现在假设每按一次需要花费一个时间段,等待时间需要花费两个时间段。 现在给出一串字符,需要计算出它所需要花费的时间。

########## 输入描述 ##########

一个长度不大于100的字符串,其中只有手机按键上有的小写字母

########## 输出描述 ##########

输入可能包括多组数据,对于每组数据,输出按出Input所给字符串所需要的时间

#include <stdio.h>int main(){    char c[110];    int count = 0;    int i;    while(gets(c) != NULL){        for(i = 0; c[i + 1] != '\0'; i++){            //处理从a到o,ascii码为97到111            int num = c[i] % 3;            if(c[i] % 3 == 0){                num = 3;            }            if(c[i] >= 97 && c[i] <= 111){                if((num == 1 && c[i + 1] - c[i] <= 2 && c[i + 1] - c[i] >= 0)                   || (num == 2 && (((c[i + 1] - c[i]) <= 1 && c[i + 1] - c[i] >= 0) || ((c[i] - c[i + 1]) <= 1 && c[i] - c[i + 1] >= 0)))                   || (num == 3 && c[i] - c[i + 1] <= 2 && c[i] - c[i + 1] >= 0))  {                    count = count + num + 2;                }else{                    count = count + num;                }            }            //处理从t到v,ascii码为116到118            else if(c[i] >= 116 && c[i] <= 118){                if(((c[i] + 1) % 4 == 1 && c[i + 1] - c[i] <= 2 && c[i + 1] - c[i] >= 0)                   || ((c[i] + 1) % 4 == 2 && (((c[i + 1] - c[i]) <= 1 && c[i + 1] - c[i] >= 0) || ((c[i] - c[i + 1]) <= 1 && c[i] - c[i + 1] >= 0)))                   || ((c[i] + 1) % 4 == 3 && c[i] - c[i + 1] <= 2 && c[i] - c[i + 1] >= 0))  {                    count = count + (c[i] + 1) % 4 + 2;                }else{                    count = count + (c[i] + 1) % 4;                }            }            //处理从w到z,ascii码为119到122            else if(c[i] >= 119){                if(c[i + 1] >= 119){                    count = count + (c[i] + 2) % 5 + 2;                }else{                    count = count + (c[i] + 2) % 5;                }            }            //处理从p到s,ascii码为112到115            else{                 if(((c[i] + 4) % 5 == 1 && c[i + 1] - c[i] <= 3 && c[i + 1] - c[i] >= 0)                    || ((c[i] + 4) % 5 == 2 && ((c[i + 1] - c[i] <= 2 && c[i + 1] - c[i] >= 0) || (c[i] - c[i+1] <= 1 && c[i] - c[i + 1] >= 0)))                    || ((c[i] + 4) % 5 == 3 && ((c[i] - c[i + 1] <= 2 && c[i] - c[i + 1] >= 0) || (c[i + 1] - c[i] <= 1 && c[i + 1] - c[i] >= 0)))                    || ((c[i] + 4) % 5 == 4 && c[i] - c[i + 1] <= 3 && c[i] - c[i + 1] >= 0)) {                    count = count + (c[i] + 4) % 5 + 2;                }else{                    count = count + (c[i] + 4) % 5;                }            }        }        //处理最后一个元素        //当为a到o时        if(c[i] >= 97 && c[i] <= 111){            if(c[i] % 3 == 0){                printf("%d\n", count + 3);            }else{                printf("%d\n", count + c[i] % 3);            }        }        //当为t到v时        else if(c[i] >= 116 && c[i] <= 118){             printf("%d\n", count + (c[i] + 1) % 4);        }        //当为w到z时        else if(c[i] >= 119){            printf("%d\n", count + (c[i] + 2) % 5);        }        //当为p到s时        else{            printf("%d\n", count + (c[i] + 4) % 5);        }        count = 0;    }}
另一种高效简单解决方法:

#include <stdio.h>int main(){    int alpha[26] = {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 1, 2, 3, 4};//定义26个字母在手机按键中点击所需的时间    int keys[26] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8};//定义26个字母对应的小组    int count = 0;    char str[100];    char pre = '#';//定义前一个字符    while(gets(str) != NULL){        for(int i = 0; str[i] != '\0'; i++){            //如果前一个字符和现字符相等,则加2            if(keys[pre - 97] == keys[str[i] - 97]){                count += 2;            }            count += alpha[str[i] - 97];            pre = str[i];        }        printf("%d\n", count);        count = 0;        pre = '#';    }    return 0;}
运行结果:

图3.1 运行结果


4、一个整数总可以拆分为2的幂的和,例如: 7=1+2+4 7=1+2+2+2 7=1+1+1+4 7=1+1+1+2+2 7=1+1+1+1+1+2 7=1+1+1+1+1+1+1 总共有六种不同的拆分方式。
再比如:4可以拆分成:4 = 4,4 = 1 + 1 + 1 + 1,4 = 2 + 2,4=1+1+2。
用f(n)表示n的不同拆分的种数,例如f(7)=6. 要求编写程序,读入n(不超过1000),输出f(n)%1000000000。

########## 输入描述 ########## 
每组输入包括一个整数:N(1<=N<=1000)。
########## 输出描述 ########## 
对于每组数据,输出f(n)%1000000000。

#include <stdio.h>int main(){    int num = 0;    int a[1010];    a[0] = 1;    for(int i = 1; i <= 1010; i++){        if(i == 1){            a[i] = 1;        }else if(i % 2 == 0){            a[i] = (a[i - 1] + a[i / 2]) % 1000000000;        }else{            a[i] = a[i - 1];        }    }    while(scanf("%d", &num) == 1){        printf("%d\n", a[num]);    }    return 0;}
运行结果:

图4.1 运行结果


5、输入一个整数n,输出n的阶乘。
########## 输入描述 ########## 
一个整数n(1<=n<=20)
########## 输出描述 ########## 
n的阶乘

#include <stdio.h>int main(){    int num;    long long a[21];    a[0] = 1;    a[1] = 1;    for(int i = 2; i <= 20; i++){        a[i] = i * a[i - 1];    }    while(scanf("%d", &num) == 1){        printf("%I64d\n", a[num]);    }}
运行结果:

图5.1 运行结果


1 0