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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值