[英]Last repeating character in a string
我正在寻找一种解决方案,以找到字符串中最后一个重复的字符,该字符串显示“您今天好吗”,应该以y
作为答案。 我尝试使用链接哈希映射来获取有序的插入,但是我将d作为最后重复的插入。
String testString = "how are you doing today";
char[] testStringArray = testString.toCharArray();
Map<Character,Integer> map = new LinkedHashMap<>();
for( char i : testStringArray) {
if (!(i==' ')) {
if(map.containsKey(i) ) {
map.put(i, map.get(i)+1);
} else {
map.put(i, 1);
}
}
}
System.out.println(map);
List<Entry<Character, Integer>> list = new ArrayList<>(map.entrySet());
ListIterator<Entry<Character, Integer>> it = list.listIterator(list.size());
while(it.hasPrevious()) {
if(it.previous().getValue() > 1)
System.out.println(it.previous().getKey());
}
}
感谢帮助。
此代码从最后一个字符开始扫描,并检查它是否存在于第一个字符之前的其余子字符串中:
String str = "how are you doing today";
int len = str.length();
int i = len - 1;
for (; i >= 1; i--) {
if (str.substring(0, i).contains(str.charAt(i) + "")) {
break;
}
}
if (i == 0) {
System.out.println("no repeating character");
} else
System.out.println(str.charAt(i));
您可以使用使用Set
的简单方法。 从String的char数组中读取元素后,请继续将其添加到Set
(使用toCharArray()
),如果add()
操作的返回值为false,则意味着该元素已被添加。 保留一个包含“最新的最后一个元素”的char变量。 只需在循环结束时打印即可。
一个简单的解决方案是向后遍历字符,并使用lastIndexOf
查找该字符的先前位置:
for (int i = testString.length() - 1; i > 0; --i) {
char ch = testString.charAt(i);
if (testString.lastIndexOf(ch, i - 1) != -1) {
return ch;
}
}
// Handle no repeating character found.
发生这种情况是因为LinkedHashMap保持加法顺序,并且y
在给定字符串的d
之前插入,并且当您从最后一次进行迭代时,它首先读取d
。
为了实现你想要的,我建议
- 从末尾读取您的字符串,然后将count插入LinkedHashMap中
- 从开始迭代LinkedHashMap以获得所需的输出。
希望这可以帮助。
您可以使用ArrayList或Set代替LinkedHashMap来使用此代码,没有必要。 这是我的代码:
public static Character getLastRepeatingCharacter(String src) {
Character defaultChar = null;
char[] srcCharArr = src.toCharArray();
List<Character> list = new ArrayList<Character>();
final int length = srcCharArr.length;
for(int idx = 0; idx < length; idx++) {
if (srcCharArr[idx] == ' ') {
continue;
}
if (list.contains(srcCharArr[idx])) {
defaultChar = srcCharArr[idx];
}else {
list.add(srcCharArr[idx]);
}
}
if (list.size() == length) {
defaultChar = srcCharArr[length-1];
}
return defaultChar;
}
您发布的代码中有两个错误:1)在LinkedHashMap
排序,以及2)在迭代器循环中两次调用previous()
。
要从LinkedHashMap
获得所需的顺序,您需要插入顺序。 但是更新映射中已经存在的值不会更改插入顺序。 从规格 :
请注意,如果将密钥重新插入到映射中,则插入顺序不会受到影响。 (如果在调用之前m.containsKey(k)将立即返回true时调用了m.put(k,v),则将密钥k重新插入到映射m中。)
要解决此问题,您必须删除条目并再次插入。 代替:
map.put(i, map.get(i) + 1);
你必须做:
int old = map.get(i);
map.remove(i);
map.put(i, old + 1);
第二个问题是,您在向后迭代的迭代器循环中调用了previous()
两次。 找到所需条目后,这会产生副作用,即再次推进迭代器。 您需要缓存previous()
的结果并使用两次。 因此,代替:
while (it.hasPrevious()) {
if (it.previous().getValue() > 1)
System.out.println(it.previous().getKey());
}
您需要执行以下操作:
while (it.hasPrevious()) {
Entry<Character, Integer> prev = it.previous();
if (prev.getValue() > 1)
System.out.println(prev.getKey());
}
(我怀疑您可能已经找到并修复了此问题,因为有了此修复程序,但没有LinkedHashMap
修复程序,结果是d
与您所看到的匹配。)
从根本上讲,我认为您采用的是正确的方法。 本质上是这样的:
一种简化的变体是迭代从字符串中向后获取字符,然后在映射中查找以找到频率大于1的第一个字符 。 字符串保持顺序,因此映射不必如此。 因此,您可以避免使用LinkedHashMap
和维护其插入顺序所需的额外工作。 您将执行以下操作:
for (int i = testString.length() - 1; i >= 0; i--) {
char ch = testString.charAt(i);
if (map.containsKey(ch) && map.get(ch) > 1) {
System.out.println(ch);
}
}
事实证明,使用Java 8 lambda和流可以使用更简单的方法来完成这两种操作。 首先,在给定字符串input
的情况下,生成字符出现的直方图(频率图),请执行以下操作:
Map<Character, Long> hist =
input.chars()
.mapToObj(ch -> (char)ch)
.filter(ch -> ch != ' ')
.collect(groupingBy(ch -> ch, counting()));
这里的皱纹是, chars()
方法返回一个IntStream
与每个char
包含在值int
。 因此,必须将其转换为mapToObj()
中的char
才能将其转换为Stream<Character>
。 请注意,我依赖于java.util.stream.Collectors.*
静态导入来获取简洁的分组/计数收集器。
获得直方图后,就可以再次串流字符,并使用reduce()
技巧获取最后一个元素:
input.chars()
.mapToObj(ch -> (char)ch)
.filter(ch -> ch != ' ')
.filter(ch -> hist.get(ch) > 1L)
.reduce((a, b) -> b);
放在一起,您将拥有:
Optional<Character> lastRepeat(String input) {
Map<Character, Long> hist =
input.chars()
.mapToObj(ch -> (char)ch)
.filter(ch -> ch != ' ')
.collect(groupingBy(ch -> ch, counting()));
return input.chars()
.mapToObj(ch -> (char)ch)
.filter(ch -> ch != ' ')
.filter(ch -> hist.get(ch) > 1L)
.reduce((a, b) -> b);
}
这将返回一个Optional
其中包含字符串中的最后一个重复的字符;如果没有重复的字符,则返回一个空的Optional
。
String str="how are you doing today";
char charArr[]=str.toCharArray();
HashMap<Character,Integer> hMap=new HashMap();
for(int i=0;i<charArr.length;i++)
{
if(hMap.containsKey(charArr[i]))
{
int count=hMap.get(charArr[i]);
hMap.put(charArr[i],count+1);
}else
{
hMap.put(charArr[i], 1);
}
}
System.out.println(hMap);
for(int i=charArr.length-1;i>=0;i--)
{
if(hMap.get(charArr[i])>1)
{
System.out.println("The Last Repeated Character is :"+charArr[i]);
break;
}
}
输出:
{ =4, a=2, d=2, e=1, g=1, h=1, i=1, n=1, o=4, r=1, t=1, u=1, w=1, y=2}
The Last Repeated Character is : y
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.