PAT-A1050 String Subtraction

Given two strings S​1​​ and S​2​​, S=S​1​​−S​2​​ is defined to be the remaining string after taking all the characters in S​2​​ from S​1​​. Your task is simply to calculate S​1​​−S​2​​ for any given strings. However, it might not be that simple to do it fast.

Input Specification:

Each input file contains one test case. Each case consists of two lines which gives S​1​​ and S​2​​, respectively. The string lengths of both strings are no more than 10​4​​. It is guaranteed that all the characters are visible ASCII codes and white space, and a new line character signals the end of a string.

Output Specification:

For each test case, print S​1​​−S​2​​ in one line.

Sample Input:

They are students.
aeiou

Sample Output:

Thy r stdnts.

 

 


爲什麼使用set呢?因爲兩個字符串的長度都說了最大是10000,但是第二個是要刪除的元素啊,10000個一定會重複(可見字符一共就那麼一百多個),因此我這裏使用set得到一個無重複字符數組。然後遍歷。使用flag標誌變量,某一位應被刪掉就給他標記flase,輸出的時候true才輸出

#include <iostream>
#include <string.h>
#include <set>
#include <algorithm>
#define maxsize 10002
using namespace std;
int main(){
	char one[maxsize];
	char two[maxsize];
	bool flag[maxsize];
	fill(flag,flag+maxsize,1);
	fgets(one,maxsize,stdin);
	fgets(two,maxsize,stdin);
	int sizeone=strlen(one)-1;
	int sizetwo=strlen(two)-1;
	set<char> data;
	for(int i=0;i<sizetwo;i++){
		data.insert(two[i]);
	}
	for(set<char>::iterator lt=data.begin();lt!=data.end();lt++){
		for(int j=0;j<sizeone;j++){
			if(*lt==one[j]){
				flag[j]=false;
			}
		}
	}
	for(int k=0;k<sizeone;k++){
		if(flag[k]){
			printf("%c",one[k]);
		}
	}
	return  0; 
} 

Tips:

       由於測試範圍導致的測試用例通不過:找到輸入數據中心最大的測試數,然後在這個範圍上根據語法語義找上限。比如這道題告訴我們上限是10000,我們使用的是字符數組保存字符串,要注意字符串要以'\0',結尾,多佔一個位置,使用fgets讀取,又多佔一個‘\n’換行符。所以最終的數據範圍最大是10002.(其實,要我說啊,咱們雖然在金錢上不能豪一下,但是在內存上可以揮霍一下啊,最大是10000,我給開10100,多給開100個,有啥問題都能包含進去了)

 


但是嚴格來講,上面仍然是暴力算法。我們來從數據結構的角度來想這道題,散列!

#include <cstdio>
#include <cstring>
// 最大長度10^4,再加上行末的\n和字符串結尾的\0,所以最大長度定位10^4 + 2
#define MAX_LENGTH 10002
#define L 256
int main() {
    char str1[MAX_LENGTH], str2[MAX_LENGTH];
    bool marked[L] = {false};                    //全部初始化爲false
    fgets(str1, MAX_LENGTH, stdin);
    fgets(str2, MAX_LENGTH, stdin);
    
    // 遍歷標記刪去的字符
    for(int i = 0, l = (int)strlen(str2); i < l; i++){
        marked[str2[i]] = true;                 //注意,char會自動轉換爲對應的int
    }
    
    // 遍歷輸出
    for(int i = 0, l = (int)strlen(str1); i < l; i++){
        if(marked[str1[i]]) continue;
        putchar(str1[i]);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章