C語言程式設計之字串處理
C語言程式設計-字串處理
第一題:迴文數判斷
問題描述】
迴文是正讀和倒讀都一樣的句子。讀入一個最大長度不超過50個字元的句子,判斷其是否是迴文。
【輸入形式】
輸入一個最大長度不超過50個字元的句子
【輸出形式】
Yes/No
【輸入樣例】
abcba
【輸出樣例】
Yes
【樣例說明】
輸入abcba,判斷出它是迴文。
#include <stdio.h> #include <stdlib.h> #include<string.h> int main() { char str[50]; int i,j,n; gets(str); //printf("%s",str); n = strlen(str); for(i=0,j=n-1;i<j;i++,j--){ if(str[i] != str[j]) break; } if(i<j){ printf("No"); }else{ printf("Yes"); } return 0; }
解釋:
基本思路就是遍歷字元陣列,從前往後與從後往前的字元進行的對比;
結束條件是字元不相等時,跳出迴圈;
判斷i與j的大小關係即可;
第二題:求兩個字串的差集
問題描述】要求計算A-B。A和B都是字串 —即從字串A中把字串B所包含的字元全刪掉,剩下的字元組成的就是字串A-B。
【輸入形式】輸入在2行中,先後給出字串A和B。兩字串的長度都不超過104,並且保證每個字串都是由可見的ASCII碼和空白字元組成,最後以換行符結束。
【輸出形式】
在一行中打印出A-B的結果字串,如果 A-B為空串,則列印一空行。
【樣例輸入】
I love GPLT! It's a fun game!
aeiou
【樣例輸出】
I lv GPLT! It's fn gm!
#include <stdio.h> #include <string.h> int main() { char str1[1001]; char str2[1001]; char ch[1001]; int i,count=0; gets(str1); gets(str2); int n=strlen(str1); for(i=0;i<n;i++) { //如果str1中的不在str2中,則儲存 if(strchr(str2,str1[i])==NULL) ch[count++]=str1[i]; } printf("%s",ch); return 0; }
解釋:
首先定義了兩個字串;
判斷長的字元陣列在短的字元陣列中是否存在;
我們使用的函式時strchr,如果沒有找到,則返回NUll;
所以我們可以寫成strchr(str2,str1[i])==NULL;把沒有找到字元(即不重複的字元)
儲存到新的陣列中,數字下標自加;
最後輸出新的陣列。
第三題:字母順序數字逆序
【問題描述】輸入任意的由字母和數字組成的字串,將其中字母直接輸出,數字逆序輸出S6.7。
【輸入形式】任意的由字母和數字組成的字串,#結束,中間沒有空格。
【輸出形式】將其中字母直接輸出,數字逆序輸出,不含#。
【樣例輸入】number345reverse#
【樣例輸出】numberreverse543
/*
* 1.定位數字
* 2.逆序數字--S1
* 3.S1放在字元最後
* 4.輸出
* */
#include <stdio.h>
#include "string.h"
#define N 10001
int main()
{
char str1[1001],c;
// gets(str1);
//輸入字串
int index ;
for (index = 0; index <N-1&&(c=getchar()) !='#'; ++index)
{
str1[index] =c;
}
str1[index]='\0';
//定義三個字元陣列
char count_str[1001];
char count_int[1001];
char count_re[1001];
int num=0;
int n = strlen(str1);
//輸出字元
for (int i = 0; i < n; ++i)
{
if (str1[i]>=';' &&str1[i]<='z')
{
count_str[num++]=str1[i];
}
}
//判斷數字48-57
int k=0;
for (int i = 0; i < n; ++i)
{
if (str1[i]>=48 && str1[i]<=57)
{
count_int[k++]=str1[i];
}
}
//數字反轉
int m=strlen(count_int);
int b=0;
for (int i = m-1; i >=0 ; i--)
{
count_re[b++]=count_int[i];
}
// puts(count_str);
// puts(count_int);
// puts(count_re);
puts(strcat(count_str,count_re));
return 0;
}
解釋:
首先需要明確字串需要一個數組,數字一個數組,逆轉的數字一個數組;
首先提取字串,根據字元的ASCII碼設定範圍來確定我們需要的字元;
這裡的起始點為什麼是";",按理說應該是"a"-"z"的,但是在測試用例裡面是有";";
老話說的好:既然不能改變,那麼只能默默接受;
然後將符合條件的字元存到陣列中;
同理數字也是一樣;
數字反轉只需要在陣列中從後往前輸出即可;
使用strcat連線兩個陣列即可。
第四題:整數轉R進位制數
問題描述】鍵盤輸入任一個大於等於0的整數,輸出R進製表示的字串
【輸入形式】
兩個空格隔開的整數, 一個是>=0的 整數,一個整數是R,(2<=R<=16)
【輸出形式】
R進位制字串
【樣例輸入1】
29 2
【樣例輸出1】
11101
【樣例輸入】
29 16
【樣例輸出】
1D
#include <stdio.h>
#define N 20
#include "string.h"
int main() {
int n,m;
scanf("%d%d",&n,&m);
int jz[N];
//元素個數
int i=0;
while (n!=0){
//將餘數存到陣列中,迭代n,n==0時輸出;
jz[i++]=n%m;
n=n/m;
}
//後面取元素判斷是否<10;
for (int j = i-1; j>=0; j--) {
int k=jz[j];
if (k<10) printf("%d",k);
else printf("%c",k+55);
}
return 0;
}
解釋:
首先需要知道進位制轉換的原理:
除R取餘,然後再逆取餘數,如圖所示;
將餘數儲存到陣列中,再從後往前輸出即可得出進位制數;
但是我們需要判斷元素的大小,如果大於/小於10;需要做相應的判斷處理;
這裡我們小於10處理,小於10輸出,否則將字元+55;
因為16進位制,+55正好是在大寫字元的範圍中,10+55-->65(A)。
可能會問怎麼知道陣列中的元素個數,這個就是i變數的作用,相當於計數器。
第五題:字串基本操作
編寫一個程式,輸入一個正整數n和字串A,對字串A作如下處理:
- 去掉重複的字元
- 去掉所有非字母非數字的字元
- 將字母大小寫互換
- 按照字元的ASCII碼從大到小排序
最後在同一行裡輸出n個處理後的字串A
【輸入形式】
- 輸入正整數n和字串A,0<n<10,A長度小於80,輸入以回車結束
【輸出形式】
- 輸出結果為目標字串
- 輸出後面無換行符
【樣例輸入】
2 abcd123
【樣例輸出】
DCBA321DCBA321
#include <stdio.h>
#include "string.h"
#define N 10000
int main() {
int n;
scanf("%d",&n);
char str[N];
char str2[N];
char str3[N];
fgets(str, 100, stdin);
int len = strlen(str);
int count=0;
//處理重複字串
for (int i = 0; i < len; ++i) {
int index=0;
for (int j = 0; j < i; ++j) {
if (str[i]==str[j]){
index=1;
}
}
if (index==0){
str2[count++]=str[i];
}
}
// 去掉所有去掉所有非字母非數字的字元
int k=0;
int len2 = strlen(str2);
for (int i = 0; i <len2 ; ++i) {
if ((str2[i]>='A' && str2[i]<='Z' )||(str2[i]>='a' && str2[i]<='z')||(str2[i]>='0'&&str2[i]<='9')){
//大小寫互換
if ((str2[i]>='A' && str2[i]<='Z' )||(str2[i]>='a' && str2[i]<='z')){
str2[i] ^=32;
}
str3[k++]=str2[i];
}
}
// puts(str2);
// puts(str3);
//通過氣泡排序進行由大到小
int len3 = strlen(str3);
for (int i=0;i<len3-1;i++)
for (int j=0;j<len3-i-1;j++)
{
if (str3[j]<str3[j+1]) // 這裡是從大到小排序,如果是從小到大排序,只需將“<”換成“>”
{
int temp;
temp=str3[j];
str3[j]=str3[j+1];
str3[j+1]=temp;
}
}
char str4[N];
int num=0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j <len3 ; ++j) {
str4[num++]=str3[j];
}
}
puts(str4);
return 0;
}
解釋:
首先去掉重複的字元:
這裡我們採用的是二層迴圈,意思是將字串中的第一個字元與本身所有的字元進行對比;
定義一個記錄變數index並初始為0-->表示沒有相同的字元,如果有相同的,index=1;
在第一層迴圈裡判斷index,若index=0;則將該字元存到新的陣列中。
for (int i = 0; i < len; ++i) {
int index=0;
for (int j = 0; j < i; ++j) {
if (str[i]==str[j]){
index=1;
}
}
if (index==0){
str2[count++]=str[i];
}
}
第二步:去掉所有非字母非數字的字元與將字母大小寫互換整合
這個判斷字元ASCII的範圍即可;在篩選出符合的的字元後在判斷是否為大小寫:
轉換為大小寫的騷操作是網上的大佬所寫,大體意思是:進行異或操作,具體連結放到博文結尾。
for (int i = 0; i <len2 ; ++i) {
if ((str2[i]>='A' && str2[i]<='Z' )||(str2[i]>='a' && str2[i]<='z')||(str2[i]>='0'&&str2[i]<='9')){
//大小寫互換
if ((str2[i]>='A' && str2[i]<='Z' )||(str2[i]>='a' && str2[i]<='z')){
str2[i] ^=32;
}
str3[k++]=str2[i];
}
}
第三步:按照字元的ASCII碼從大到小排序
這裡採用的是陣列中的氣泡排序,不多解釋,如果不理解的話看前面部落格:
https://www.cnblogs.com/xbhog/p/11741079.html
for (int i=0;i<len3-1;i++)
for (int j=0;j<len3-i-1;j++)
{
if (str3[j]<str3[j+1]) // 這裡是從大到小排序,如果是從小到大排序,只需將“<”換成“>”
{
int temp;
temp=str3[j];
str3[j]=str3[j+1];
str3[j+1]=temp;
}
}
最後:由題意可知需要輸出n次並不換行;
然後再迴圈內遍歷字元存到新的陣列中。
for (int i = 0; i < n; ++i) {
for (int j = 0; j <len3 ; ++j) {
str4[num++]=str3[j];
}
}
總結:
上述題目的解不是唯一,例題中的解是我所理解並執行成功的,如果有不對的地方,歡迎指出。
關於大小寫的轉換部落格來連結:https://blog.csdn.net/zkx981105/article/details/78525672