给定两个字符串,找到它们之间的公共字符数。
实施例
对于s1 =" aabcc"和s2 =" adcaa",输出应该是 commonCharacterCount(s1,s2)= 3。
字符串有3个常用字符 - 2" a" s和1" c"。
我已经坚持这个问题很多了,我已经尝试了很多方法来解决这个问题,但我无法弄明白。我有如何解决它的主要想法,但我不能将其转移到代码。
我的方法是将字符串的字符放在它们自己的ArrayList中,并使用嵌套循环来迭代它们,比较相似的字符并将计数存储在int值中。我没有任何代码,因为我尝试了许多不同的尝试来改变我的代码,但没有运气。
我使用了两个嵌套的for循环,它们彼此分开:
for(int i = 0; i<firstString.size(); i++){
for(int j = 0; j<secondString.size(); j++){
if(firstString.get(i) == secondString.get(j){
lettersInCommon++;
secondString.remove(j);
}
}
}
和
for(int i = 0; i<secondString.size(); i++){
for(int j = 0; j<firstString.size(); j++){
if(firstString.get(i) == secondString.get(j){
lettersInCommon2++;
firstString.remove(i);
}
}
}
所以在这些循环运行之后,我会根据它们的大小返回两个lettersinCommon int之间的差异以避免负面。所以如果lettersInCommon&gt; lettersInCommon2 - return lettersInCommon - lettersInCommon2;反之亦然。
我不希望任何人告诉我如何对此进行编码,我只想建议我的逻辑,看看我是否可以简化这个问题,或者我是否遗漏了什么。
我还想声明这段代码适用于某些测试用例,但不是全部。
我一直在考虑我收到的评论,并且到目前为止:
ArrayList<Character> firstString = new ArrayList<Character>();
ArrayList<Character> secondString = new ArrayList<Character>();
int lettersInCommon = 0;
for(int i = 0; i<s1.length(); i++){
firstString.add(s1.charAt(i));
}
for(int i = 0; i<s2.length(); i++){
secondString.add(s2.charAt(i));
}
Collections.sort(firstString);
Collections.sort(secondString);
for(char c : firstString){
if(firstString.contains(c) && secondString.contains(c)){
lettersInCommon++;
secondString.remove(s2.indexOf(c));
}
}
我非常接近,但是我得到的错误是这一行的超出界限
secondString.remove(s2.indexOf(c));
有没有人对此有任何见解?
答案 0 :(得分:2)
你可以去寻找地图。它可能不是性能方面的最佳解决方案,而是直观易懂的解决方案。首先,迭代每个字符串并使用它们的外观计数收集每个(不同的)字符。然后,比较两个地图(即字符)的键集以及在两个地图中找到的每个字符,将它与两个地图中的最小外观数一起存储。所以像这样:
// first collect characters with their appearance count in maps:
"aabcc" -> 2xa, 1xb, 2xc
"adcaa" -> 3xa, 1xc, 1xd
// now, get all shared characters with their minimum count from both maps:
a -> min(2,3) = 2
b -> not shared
c -> min(2,1) = 1
d -> not shared
我想这可以使用Stream API以很酷的方式实现,但这将是一个非常复杂的声明,不确定您是否有使用Streams的经验。
编辑:这是使用Streams的一个解决方案。我打赌有更好的,无论是表现方面还是方法,但它是我尝试过的第一件事:
public static void main(String[] args) {
System.out.println(commonCharacterCount("aabcc","adcaa"));
}
public static int commonCharacterCount(String s1, String s2) {
Map<Character, Integer> s1CharacterCount = getCharacterCount(s1);
Map<Character, Integer> s2CharacterCount = getCharacterCount(s2);
return s1CharacterCount.keySet().stream()
.filter(s2CharacterCount.keySet()::contains)
.mapToInt(c -> Math.min(s1CharacterCount.get(c), s2CharacterCount.get(c)))
.sum();
}
public static Map<Character, Integer> getCharacterCount(String s) {
Map<Character, Integer> characterCount = new HashMap<>();
for (char c: s.toCharArray()) {
characterCount.put(c, characterCount.computeIfAbsent(c, count -> 0) + 1);
}
return characterCount;
}
答案 1 :(得分:1)
==
contains()
为你做这件事。 您甚至不需要contains()
,因为remove()
会告诉您是否删除了某些内容。所以你需要的只是:
List<Character>
答案 2 :(得分:0)
使用s1.charAt(i) == s2.charAt(i)
比较。没有必要将字符串放入arrayList。
编辑:您需要添加条件语句,以确保在字符串长度不同时不会超出范围。
答案 3 :(得分:0)
为您提供的每个字符串创建字母计数的映射。然后将键相互比较,如果两个单词中都包含字母,则从两个地图中获取最低计数。试试这个
public static void main(String[] args)
{
String str1 = "aabbcc";
String str2 = "abcddc";
HashMap<Character, Integer> str1LetterCounts = createLetterCountMap(str1);
HashMap<Character, Integer> str2LetterCounts = createLetterCountMap(str2);
HashMap<Character, Integer> commonCounts = new HashMap<>();
Set<Character> possibleCommonCharacterList = str1LetterCounts.keySet();
for(Character letter : possibleCommonCharacterList)
{
if(str2LetterCounts.containsKey(letter))
{
Integer count1 = str1LetterCounts.get(letter);
Integer count2 = str2LetterCounts.get(letter);
commonCounts.put(letter, count1 <= count2 ? count1 : count2);
System.out.println("Common Character " + letter + " : " + (count1 <= count2 ? count1 : count2));
}
}
}
public static HashMap<Character, Integer> createLetterCountMap(String word)
{
HashMap<Character, Integer> letterCountsForWord = new HashMap<>();
for(int i = 0; i < word.length(); i++)
{
Character key = word.charAt(i);
if(letterCountsForWord.containsKey(key))
{
letterCountsForWord.put(key, letterCountsForWord.get(key) + 1);
}
else
letterCountsForWord.put(key, 1);
}
return letterCountsForWord;
}
输出
Common Character a : 1
Common Character b : 1
Common Character c : 2