输入一个字符串,过滤掉非首次出现的重复字符

本文介绍了一个Java程序,该程序能够接收用户输入的字符串,并通过使用LinkedHashMap来过滤掉字符串中所有非首次出现的重复字符。文章提供的代码示例展示了如何实现这一功能。

 输入一个字符串,过滤掉非首次出现的重复字符,例如:"abcdeacdag",过滤后的字符串为"abcdeg"

import java.util.*;
public class FilterChar_1 {
	public static void main(String[] args){
		Scanner sc =new Scanner(System.in);
			while(sc.hasNextLine()){
				String str=sc.nextLine();
				filter(str);
				
			}
			sc.close();
		
		
	}
	public static void filter(String str){
		StringBuilder sb =new StringBuilder();
		//LinkedHashMap底层数据结构为链表,能够记住存入键的顺序。
		LinkedHashMap<Character,Integer> hash = new LinkedHashMap<Character,Integer>();
		char [] ch =str.toCharArray();
		
		for(char temp : ch){
			//若字符在字符串中已经出现了,则将该字符置于已出现字符的位置(键的唯一性),并始终将该重复出现的字符对应的次数(值)置于1
			if(hash.containsKey(temp))
				hash.put(temp, 1);
			else
				//若字符在字符串中未出现,则将该字符放入到集合中
				hash.put(temp, 1);
		}
			//遍历LinkedHashMap集合中的键,并依次放入字符串容器中
			for(char ch1 : hash.keySet()){
				sb.append(ch1);
				
			}
			String str1 =new String(sb);
			System.out.println(str1);
					
				
					
	}	
}


<think>嗯,用户想要用C语言实现删除字符串重复字符的方法。我之前学过一些字符串处理的例子,可能需要先回忆一下相关的知识。首先,记得字符串在C语言中是字符数组,以空字符结尾。所以处理的时候需要遍历每个字符,并判断是否已经出现过。 之前看到过两种方法,一种是使用辅助数组来记录已经出现的字符,比如引用4中的代码。他们定义了一个大小为128的数组str,用来记录ASCII字符是否出现过。遍历原字符串时,检查当前字符对应的ASCII位置是否为0,如果是,就标记为已出现,并保留该字符。否则跳过。这种方法的时间复杂度是O(n),因为只需要遍历一次,效率很高。 另一种方法可能是类似引用5中的方式一,使用双重循环,逐个检查每个字符是否在之前出现过。不过这种方法的时间复杂度是O(n²),对于长字符串可能效率不高。所以可能更好的方法是第一种,利用哈希表的思想,用辅助数组来记录字符出现情况。 用户提供的引用4和引用5的代码示例都涉及到了这些方法。需要确保代码正确处理字符串的结束符,并且处理各种字符的情况,比如大小写是否区分,但根据问题描述,可能默认是区分大小写的。 然后需要整理步骤,首先输入字符串,然后遍历每个字符,使用辅助数组记录是否已经存在。如果不存在,就保留该字符,否则跳过。最后在结果字符串末尾添加空字符。 另外要注意代码的健壮性,比如输入字符串的长度是否超过预设的数组大小,比如引用4中的N是100,可能在实际应用中需要动态分配或者限制输入长度。 然后按照用户的要求,给出具体的实现方法,并解释每一步的作用。同时需要确保代码符合C语言的语法,比如指针的使用,数组索引的正确处理。 可能还需要比较不同方法的优缺点,比如辅助数组法效率高,而双重循环法虽然空间复杂度低,但时间效率差。用户可能更倾向于高效的解决方案,所以重点介绍辅助数组的方法。 最后,生成相关问题,比如如何优化,如何处理大小写,或者不同应用场景下的选择等。</think>以下是使用C语言实现删除字符串重复字符的两种典型方法及其实现步骤: ### 方法一:哈希表法(时间复杂度O(n)) ```c #include <stdio.h> #define N 100 int main() { char input[N] = {0}; printf("输入字符串: "); scanf("%s", input); char hash[128] = {0}; // ASCII码哈希表[^4] int k = 0; for (int i = 0; input[i]; i++) { if (hash[input[i]] == 0) { // 首次出现的字符 hash[input[i]] = 1; // 标记为已存在 input[k++] = input[i]; // 保留字符 } } input[k] = '\0'; // 终止符 printf("结果: %s\n", input); return 0; } ``` **实现原理**: 1. 创建哈希表`hash[128]`记录ASCII字符出现状态 2. 遍历输入字符串,通过哈希表判断字符是否重复 3. 原地修改字符串,保留重复字符 4. 时间复杂度$O(n)$,空间复杂度$O(1)$(固定128字节)[^1] ### 方法二:双重循环法(时间复杂度O(n²)) ```c #include <stdio.h> #include <string.h> void remove_duplicates(char *str) { char *result = str; int len = strlen(str); for (int i = 0; i < len; i++) { for (int j = i+1; j < len; ) { if (str[j] == str[i]) { memmove(&str[j], &str[j+1], len-j); // 移除重复字符[^5] len--; } else { j++; } } } } int main() { char str[100]; printf("输入字符串: "); scanf("%s", str); remove_duplicates(str); printf("结果: %s\n", str); return 0; } ``` **实现原理**: 1. 使用嵌套循环逐个比较字符 2. 发现重复时使用`memmove`移动后续字符 3. 时间复杂度$O(n^2)$,适合短字符串 ### 方法对比 | 特性 | 哈希表法 | 双重循环法 | |-------------|----------------|----------------| | 时间复杂度 | $O(n)$ | $O(n^2)$ | | 空间复杂度 | $O(1)$ | $O(1)$ | | 字符顺序 | 保持原序 | 保持原序 | | 适用场景 | 长字符串 | 短字符串 | ### 注意事项 1. 输入字符串长度应小于预定义数组长度 2. 哈希表法区分大小写(ASCII码不同) 3. 两种方法都保留首次出现的字符 4. 可添加`isalnum()`函数过滤字母数字字符
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值