C言語初心者です。以下の問題で困っています。
(問題)
2つの英字小文字のみからなる長さがそれぞれn,mの文字列s1(文字数n),s2(文字数m)が与えられたとする。文字列s1に含まれる文字を使って文字列s2を作ろうとしたとき足りなくなる文字の個数を表示せよ。ただし文字列を構成する文字は1度のみ使うことができる。
1<=n<=100000,1<=m<=100000
たとえば文字列s1="catfood" s2="carrot" であるとき、s2を作るにはs1にある文字c,a,tとoが一つ使えるので必要なのはrが2つとなり出力は2になります。
これをC言語で表現しようとして考えたアルゴリズムが、文字列s2の先頭の文字から最後まで順に文字列s1の要素と比較し、等しければ両方の文字列の要素を0で上書きする。これを文字列s1の要素の最後まで行い、最後に文字列s2を出力して0でない要素の個数を出力する。
例えば上記であれば最終的にs1="000f0od" s2="00rr00"となり文字列s2の0ではない要素数である2が出力されます。
コードは以下になります。
これを実行すると小規模データは結果を出力しますがn^2のオーダーのためか要素が 100000の文字列ではタイムアウトになります。
アルゴリズムが悪いのか配列以外のデータ構造を使う必要があるのか考えてもわかりません。改善点をご教授いただければ幸いです。
C
1#include <stdio.h> 2int n,m; 3char s1[100000]; 4char s2[100000]; 5//文字列s2の各要素を文字列s1の要素と比較し等しければその2つの要素を0で上書きする。 6void compare(char *s1,char *s2){ 7 for(int i=0;i<m+1;i++){ 8 for(int j=0;j<n+1;j++){ 9 if(s2[i]==s1[j]){s2[i]=s1[j]='0';} 10 } 11 } 12} 13//改変された文字列s2の要素のうち0でないものの個数をカウントする。 14int count(char *s2){ 15 int counter=0; 16 for(int i=0;i<m+1;i++){ 17 if(s2[i]!='0')counter+=1; 18 } 19 return counter; 20} 21 22int main(void){ 23 scanf("%d %d",&n,&m); 24 scanf("%s",s1); 25 scanf("%s",s2); 26 compare(s1,s2); 27 printf("%d\n",count(s2)); 28 return 0; 29}
回答4件
あなたの回答
tips
プレビュー