数据结构学习(三)
目录:
编程专练:
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);
}
运行结果:
2、输入任意4个字符(如:abcd), 并按反序输出(如:dcba)。
########## 输入描述 ##########
题目可能包含多组用例,每组用例占一行,包含4个任意的字符。
########## 输出描述 ##########
对于每组输入,请输出一行反序后的字符串。
#include <stdio.h>
#define LENGTH 4
int 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]);
}
}
运行结果: