数据结构学习(三)

数据结构学习(三)

目录:

编程专练:

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 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]);
    }
}
运行结果:

图5.1 运行结果


  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值