算法入门系列之字符串

1.26

UVA10010 

好想说这道题我做了好久~快哭了~最后还是利用了udebug那个网站,才找到了bug

这道题收获很大对于我这个代码能力不强的人,基础知识不牢的人来说多练练还是有好处的~

1.思路:这道题给定一个二维数组,然后给你多个字符串,问你这些字符串在这个二维数组中是否能找到,重点是:方向有八个:向上,向下,向左,向右,左上,左下,右上,右下。所以读懂题意非常重要!

2.一个很重要的bug就是想说

while(str[x++][y]==test[t++]);
while(a++==b++);

上面这两句代码不一样:

第一行的意思是,先x++,t++,再比较;

第二行的意思是先判断ab是否相等,a++,b++;

UVA10010
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 using namespace std;
  5 int m,n,T;
  6 char str[55][55];
  7 char test[55];
  8 int len;
  9 int call(int x,int y,int len){
 10     //向左
 11     if(x+1-len>=0){
 12             //printf("1...........
");
 13             int i=x,j=y;
 14             int t=0;
 15            // printf("%c %c",str[i][j],test[t]);
 16             while(t<len&&str[i][j]==test[t]){
 17                 i--;t++;
 18             }
 19            // printf("%d\\	",t);
 20             if(t==len)return 1;
 21 
 22     }
 23     //向右
 24     if(m-x>=len){
 25         //printf("2...........
");
 26         int i=x,j=y;
 27         int t=0;
 28         while(str[i][j]==test[t]&&t<len){
 29             i++;
 30             t++;
 31         }
 32         if(t==len)return 1;
 33     }
 34     //向上
 35     if(y+1-len>=0){
 36         //printf("3...........
");
 37         int i=x,j=y;
 38         int t=0;
 39         while(str[i][j]==test[t]&&t<len){
 40             j--;
 41             t++;
 42         }
 43         if(t==len)return 1;
 44     }
 45     //向下
 46     if(n-y>=len){
 47         //printf("4...........
");
 48         int i=x,j=y;
 49         int t=0;
 50         while(str[i][j]==test[t]&&t<len){
 51             j++;t++;
 52         }
 53         if(t==len)return 1;
 54     }
 55     //左上-+
 56     if(x+1-len>=0&&n-y>=len){
 57       // printf("5...........
");
 58             int i=x,j=y;
 59             int t=0;
 60             while(str[i][j]==test[t]&&t<len){
 61                 i--;j++;t++;
 62             }
 63             if(t==len)return 1;
 64     }
 65     //右上+-
 66     if(m-x>=len&&y+1-len>=0){
 67         //printf("6...........
");
 68         int i=x,j=y;
 69         int t=0;
 70         while(str[i][j]==test[t]&&t<len){
 71             i++;j--;t++;
 72         }
 73         if(t==len)return 1;
 74     }
 75     //左下--
 76     if(y+1-len>=0&&x+1-len>=0){
 77         //printf("7...........
");
 78         int i=x,j=y;
 79         int t=0;
 80         while(str[i][j]==test[t]&&t<len){
 81             i--;j--;t++;
 82         }
 83         if(t==len)return 1;
 84     }
 85     //右下++
 86     if(n-y>=len&&m-x>=len){
 87         //printf("8...........
");
 88         int i=x,j=y;
 89         int t=0;
 90         while(str[i][j]==test[t]&&t<len){
 91             i++;j++;t++;
 92         }
 93         if(t==len)return 1;
 94     }
 95     return 0;
 96 }
 97 int main(){
 98     //freopen("10010.txt","r",stdin);
 99     //freopen("10011.txt","w",stdout);
100     int z;
101     scanf("%d",&T);
102     while(T--){
103             getchar();
104         scanf("%d%d",&m,&n);
105         for(int i=0;i<m;i++){
106             scanf("%s",&str[i]);
107         }
108         for(int x=0;x<m;x++){
109                 for(int y=0;y<n;y++){
110                     if(str[x][y]>='A'&&str[x][y]<='Z'){
111                         str[x][y]+=32;
112                     }
113                 }
114         }
115         scanf("%d",&z);
116         while(z--){
117             scanf("%s",test);
118             int len=strlen(test);
119             for(int i=0;i<len;i++){
120                 if(test[i]>='A'&&test[i]<='Z'){
121                     test[i]+=32;
122                     //printf("%c ",test[i]);
123                 }
124             }
125             int p=0;
126             for(int x=0;x<m;x++){
127                 for(int y=0;y<n;y++){
128                         if(str[x][y]==test[0]){
129                             if(call(x,y,len)){
130                             printf("%d %d
",x+1,y+1);
131                             p=1;
132                             break;
133                         }
134                         }
135 
136                 }
137                 if(p)break;
138             }
139         }
140         if(T!=0)printf("
");
141     }
142 return 0;
143 }

 UVA10361

这道题真的是很折腾人啊~

一句话,不能轻视水题~虽然这题一点都不水~

1.题意:很简单的s1<s2>s3<s4>s5;第一个行的字符串把左右括号去掉输出,第二行把...变成s3<s2><s1><s4>输出即可;

2.思路:还是用最简单的一个一个字符查找,通过将上面的后四个字符存到四个数组中,然后按照输出要求的顺序输出。

3.我错的一个重要的地方就是两个gets函数中间使用了getchar,本意是为了过滤掉回车的,然而百度之后,得知,gets函数是读到回车结束,但是回车不存入数组中!!!!

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int main(){
    char l1[105],l2[105];
    char a[5][105];
    int T;
  //  freopen("10010.txt","r",stdin);
   // freopen("10011.txt","w",stdout);
    scanf("%d",&T);
    getchar();
    while(T--){
        gets(l1);
        //getchar();
        gets(l2);
   //     printf("%s %s",l1,l2);
        int w=0;
        int len=strlen(l1);
        int k=0;
        while(k<len){
            if(l1[k]=='<'){
                    k++;
                    int i;
                    i=0;
                while(l1[k]!='>'){
                    a[w][i++]=l1[k];
                    k++;
                }
                a[w][i++]='';
                w++;
                k++;
                i=0;
                while(l1[k]!='<'){
                    a[w][i++]=l1[k];
                    k++;
                }
                k++;
                a[w][i++]='';
                w++;
                i=0;
                while(l1[k]!='>'){
                    a[w][i++]=l1[k];
                    k++;
                }
                a[w][i++]='';
                w++;
                i=0;
                k++;
                while(i<len){
                    a[w][i++]=l1[k];
                    k++;
                }
                a[w][i++]='';
            }else
             k++;
        }
/*        for(int i=0;i<=w;i++){
            printf("%s
",a[i]);
        }*/
        int num=0;
        while(num<len){
            if(l1[num]!='<'&&l1[num]!='>'){
                printf("%c",l1[num]);
            }
            num++;
        }
        printf("
");
         int num1=0;
         int lens=strlen(l2);
        while(num1<lens){
            if(l2[num1]=='.'){
                printf("%s%s%s%s",a[2],a[1],a[0],a[3]);
                break;
            }
            printf("%c",l2[num1]);
            num1++;
        }
        printf("
");
    }
return 0;
}
UVA10361

1.27

UVA537

这道题纯暴力写的

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std;
int flag1,flag2,flag3;
double P,U,I;
char a[200];
char str[200];
int k,les;
void cal(int len){
    int i=0;
    flag1=0;flag2=0;flag3=0;
    while(i<len){
            if(a[i]=='='){
                if(a[i-1]=='P'){
                         k=0;
                        les=0;
                    while(i<len){
                        i++;
                        str[k]=a[i];
                        k++;
                        if(a[i+1]=='m'){
                            i++;
                            les=1;
                        }else if(a[i+1]=='k'){
                            i++;
                            les=2;
                        }else if(a[i+1]=='M'){
                            i++;
                            les=3;
                        }
                        if(a[i+1]=='W'){
                            i++;
                            break;
                        }
                    }
                    str[k]='';
                    P=atof(str);
                    if(les==1) P*=0.001;
                    else if(les==2) P*=1000;
                    else if(les==3) P*=1000000;
                   // printf("%s %lf
",str,P);
                    flag1=1;
                }else if(a[i-1]=='U'){
                         k=0;
                         les=0;
                    while(i<len){
                        i++;
                        str[k]=a[i];
                        k++;
                        if(a[i+1]=='m'){
                            i++;
                            les=1;
                        }else if(a[i+1]=='k'){
                            i++;
                            les=2;
                        }else if(a[i+1]=='M'){
                            i++;
                            les=3;
                        }
                        if(a[i+1]=='V'){
                                i++;
                            break;
                        }
                    }
                    str[k]='';
                    U=atof(str);
                    if(les==1) U*=0.001;
                    else if(les==2) U*=1000;
                    else if(les==3) U*=1000000;
                   // printf("%s %lf
",str,U);
                    flag2=1;
                }else if(a[i-1]=='I'){
                         k=0;
                         les=0;
                    while(i<len){
                        i++;
                        str[k]=a[i];
                        k++;
                        if(a[i+1]=='m'){
                            i++;
                            les=1;
                        }else if(a[i+1]=='k'){
                            i++;
                            les=2;
                        }else if(a[i+1]=='M'){
                            i++;
                            les=3;
                        }
                        if(a[i+1]=='A'){
                            break;
                        }
                    }
                    str[k]='';
                    I=atof(str);
                    if(les==1) I*=0.001;
                    else if(les==2)I*=1000;
                    else if(les==3)I*=1000000;
                   //printf("%s %lf
",str,I);
                    flag3=1;
                }
                }
        i++;
    }
  if(flag1&&flag2){
        printf("I=%.2lfA
",P/U);
    }else if(flag1&&flag3){
        printf("U=%.2lfV
",P/I);
    }else if(flag2&&flag3){
        printf("P=%.2lfW
",U*I);
    }
}
int main(){
    int T;
    freopen("in.txt","r",stdin);
    scanf("%d",&T);
    getchar();
    for(int num=0;num<T;num++){
        gets(a);
        int len=strlen(a);
        printf("Problem #%d
",num+1);
        cal(len);
        printf("
");
    }
return 0;
}
UVA537

UVA10815

这道题需要注意的是字符数组排序!

字符数组排序,如果使用sort的话,记住,cmp比较函数:bool cmp(char *a,char *b) 传入的参数是指针类型,所以传入的不能是字符数组,而应该是字符类型的指针!!

因此如果使用sort不能用二维数组,而使用的是指针数组,即数组里面存的是字符类型指针!所以最开始读入之后要把内容赋给指针!

因此sort的写法是sort(&strc[0],&strc[0]+num,cmp);或sort(strc,strc+num,cmp);

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 char a[1000005][205];
 7 char *strc[1000005];//指针数组(由指针组成的数组)
 8 char str[205];
 9 bool cmp(char *a,char *b){
10     if(strcmp(a,b)<0){
11         return true;
12     }return false;
13 
14 }
15 int main(){
16     freopen("in.txt","r",stdin);
17     int num=0;
18     int len;
19     int i;
20     while(scanf("%s",str)!=EOF){
21            // printf("%s",str);
22         len=strlen(str);
23         i=0;
24         int k=0;
25         int flag;
26         while(i<len){
27                 flag=0;
28        // printf("?");
29         k=0;
30         while((str[i]<='Z'&&str[i]>='A')
31               ||(str[i]<='z'&&str[i]>='a')){
32                 //  printf("%c ",str[i]);
33                 a[num][k]=tolower(str[i]);
34                // printf("%c ",str[i]);
35                 i++;
36                 k++;
37                 flag=1;
38               }
39               if(flag==1){
40                 a[num][k]='';
41                 num++;
42               }
43               i++;
44               //printf("%s",a[num]);
45         }
46     }
47      for(int i=0;i<num;i++){
48         strc[i]=a[i];
49     }
50     sort(&strc[0],&strc[0]+num,cmp);
51     printf("%s
",strc[0]);
52     for(int i=1;i<num;i++){
53         if(strcmp(strc[i-1],strc[i])==0)continue;
54         printf("%s
",strc[i]);
55     }
56 return 0;
57 }
UVA10815

1.28

UVA10115

这道题学会了strstr函数,strcpy,stract的用法!

首先 观察下列函数。

//用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。
char *strstr(char *str1, const char *str2);
//把从src地址开始且含有''结束符的字符串复制到以dest开始的地址空间。
char *strcpy(char* dest, const char *src);
//把src所指字符串添加到dest结尾处(覆盖dest结尾处的'')。
char *strcat(char *dest,char *src);

strstr函数可以用于查找句子中是否有对应的单词,其返回的是指针所指向的位置。

传入的是指针,即利用strcpy我们可以将目的字符串复制到任意指针指向位置!

利用strcat我们可以在字符串后面添加指针指向的任意位置后面的所有字符!这是指针的妙处所在!

本题的难点在于:如何替换字符,巧妙的方法是,将找到的目的字符串的位置

如上图可知,先把4赋值到str2中,然后吧str2拼接2,然后1拼接str2.

#include<cstring>
#include<cstdio>
#include<string>
#include<iostream>
using namespace std;
int main(){
    char a[100][100],b[100][100],str1[1000],str2[1000];
    int n;
    while(scanf("%d",&n)!=EOF&&n!=0){
            getchar();
        for(int i=0;i<n;i++){
            gets(a[i]);
            gets(b[i]);
        }
        gets(str1);
        for(int i=0;i<n;i++){
                char *p,*q;
            while(p=strstr(str1,a[i]),p!=NULL){
                q=p+strlen(a[i]);//指针指向匹配上的字符串的末尾位置
                strcpy(str2,b[i]);//b[i]赋值给str2
                strcat(str2,q);//str2后连接q指向位置之后的字符串
                strcpy(p,str2);//str2赋值给p指向的起始位置
            }
        }
        printf("%s
",str1);
    }
return 0;
}
UVA10115

 UVA409

这道题写的时间很长,快一个上午,最后还是看的别人的代码,发现自己应该换个思路。

1.题意:输入m个单词,n句话,在n句话中分别记录,每句话中有多少个单词在m中,重点是注意(1)n句话中找到的必须是一个独立的单词,即单词前后不能有字母!

(2)其次注意一句话中有多个相同的单词,同样计数。输出这些话中存在单词最多的话。(3)每个例子之后要输出一个空行!(4)字母部分大小写!

2.思路:我一开始想的是使用strstr函数直接查找位置,然后替换,但是无法很好地解决上(2),所以选择的思路是把每句话中的词都提取出来,然后比较。

3.输入注意:scanf函数不会读' ',所以如果下面要使用gets的话要加一句getchar,gets函数会读 ,但是不会把 写到数组里!

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
//换个思路!!
char a[25][1000],b[25][1000],temp[1000];
int c[1000];
int m,n;
bool cmps(char temp[]){
    for(int i=0;i<m;i++){
        if(strcmp(temp,a[i])==0){
            return true;
        }
    }
    return false;
}
int main(){
    int num=0;
    while(scanf("%d%d",&m,&n)!=EOF){
            memset(c,0,sizeof(c));
            num++;
            getchar();
        for(int i=0;i<m;i++){
            gets(a[i]);
            int lens=strlen(a[i]);
            for(int j=0;j<lens;j++){
                a[i][j]=tolower(a[i][j]);
            }
        }
        int Max=0;
        for(int i=0;i<n;i++){
            gets(b[i]);
            int len=strlen(b[i]);
            int ls=0;
            while(ls<len){
                    int k=0;
                    if(isalpha(b[i][ls])){
                        while(isalpha(b[i][ls])){
                            temp[k]=tolower(b[i][ls]);
                            k++;
                            ls++;
                        }
                        temp[k]='';
                        if(cmps(temp)) c[i]++;
                    }else {
                        ls++;
                    }
            }
            if(Max<c[i]) Max=c[i];
        }
        cout<<"Excuse Set #"<<num<<endl;
        for(int i=0;i<n;i++){
            if(c[i]==Max){
                cout<<b[i]<<endl;
            }
        }
        cout<<endl;
    }
return 0;
}
UVA409

UVA10878

这道题注意的是看得出来磁带每行代表字母assic的二进制数即可。还有不要把所有字符都读入再输出结果,因为行数位置。边读入边翻译就好~

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int main(){
    char str[15];
    int i=0;
    int flag;
    flag=1;
    freopen("in.txt","r",stdin);
   gets(str);
    while(gets(str)&&str[0]!='_'){
            int sum=0;
        for(int y=1;y<=5;y++){
            if(str[y]=='o'){
                sum+=(1<<(8-y));
            }
        }
        for(int y=7;y<=9;y++){
            if(str[y]=='o'){
                sum+=(1<<(9-y));
            }
        }
        printf("%c",sum);
    }

    return 0;
}
UVA10878

UVA644

这道题注意如果判断是否有一个字符包括另一个字符,那么直接判断短字符是否在长字符里即可~

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
char s[100][100];
char str[1000];
int main(){
    int num=0;
    int i;
    i=0;
    while(scanf("%s",str)!=EOF){
        if(str[0]!='9'){
            strcpy(s[i],str);
            i++;
            continue;
        }else {
            num++;
        }
        //cout<<"/////"<<i<<endl;
        int flag=0;
        for(int j=0;j<i;j++){
            for(int k=0;k<j;k++){
                int l1=strlen(s[j]);
                int l2=strlen(s[k]);
                int Max=min(l1,l2);
                int z=0;
                while(z<Max){
                    if(s[j][z]==s[k][z]){
                        z++;
                        if(z==Max)flag=1;
                    }else {
                        break;
                    }
                }
                if(flag)break;
            }
            if(flag)break;
        }
        if(!flag) cout<<"Set "<<num<<" is immediately decodable"<<endl;
        else cout<<"Set "<<num<<" is not immediately decodable"<<endl;
        i=0;
    }


return 0;
}
UVA644

——————————————————————————————————————————————————————————

意识到大学没有多长时间可以再搞ACM了,所以我想按照日记的形式记录我最后的ACM学习生涯~加油!坚持!

原文地址:https://www.cnblogs.com/Yvettey-me/p/5161734.html