在Java中按字符对字符串列表进行排序

huangapple go评论64阅读模式
英文:

Sort List of Strings by Characters In Java

问题

以下是翻译好的部分:

我正在尝试编写一个程序,根据列表中最不常见的字符对字符串列表进行排序。例如,如果列表是[apple, orange, banana],列表中的字母频率将是 a - 5,n - 3,p - 2,e - 2,l - 1,o - 1,r - 1,g - 1,b - 1。因为 orange 包含最不常见的字母,所以程序会先返回 orange,然后是 apple,最后是 banana。

到目前为止,我已经编写了代码,可以按频率对列表中的所有字母进行排序。但我需要将其应用于查找哪个字符串包含最不常见的字母。

这是我的代码:

Map<Character, Integer> elemCount = new LinkedHashMap<>();
for (String word : words)
{
    for (int i = 0; i < word.length(); i++)
    {
        if (elemCount.containsKey(word.charAt(i)))
        {
            elemCount.put(word.charAt(i), elemCount.get(word.charAt(i)) + 1);
        }
        else
        {
            elemCount.put(word.charAt(i), 1);
        }
    }
}
ArrayList<Character> sortedElems = new ArrayList<>();
elemCount.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).forEach(entry -> 
{ 
    for (int i = 1; i <= entry.getValue(); i++)
    {
        sortedElems.add(entry.getKey());
    }
}
);
System.out.println(sortedElems);
英文:

I am trying to write a program to order a list of strings by most least frequent characters within the list. For example, if the list was [apple, orange, banana] the letter frequency within the list would be a - 5, n - 3, p - 2, e - 2, l- 1, o - 1, r - 1, g - 1, b - 1. Since orange contains the most least frequent letters, the program would return orange, then apple then banana.

So far I've written the code that orders all the letters in the list by frequency. But I need to apply that to find which string contains the most least frequent letters.

Here is my code:

    Map&lt;Character, Integer&gt; elemCount = new LinkedHashMap&lt;&gt;();
    for (String word : words)
    {
        for (int i = 0; i  &lt; word.length(); i++)
        {
            if (elemCount.containsKey(word.charAt(i)))
            {
                elemCount.put(word.charAt(i), elemCount.get(word.charAt(i)) + 1);
            }
            else
            {
                elemCount.put(word.charAt(i), 1);
            }
        }
    }
    ArrayList&lt;Character&gt; sortedElems = new ArrayList&lt;&gt;();
    elemCount.entrySet().stream().sorted(Collections.reverseOrder
    (Map.Entry.comparingByValue())).forEach(entry -&gt; 
    { 
        for (int i = 1; i &lt;= entry.getValue(); i++)
        {
            sortedElems.add(entry.getKey());
        }
    }
    );
    System.out.println(sortedElems);

答案1

得分: 3

请尝试以下代码:

public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    list.add("apple");
    list.add("banana");
    list.add("orange");
    System.out.println(leastFrequentString(list));
}

private static Set<String> leastFrequentString(List<String> list) {
    Map<String, Integer> mapStringToFrequency = new HashMap<>();
    for (String s : list) {
        Map<Character, Integer> mapCharacterToFrequency = wordFrequency(s);
        int totalScore = 0;
        for (Character c : mapCharacterToFrequency.keySet()) {
            if (mapCharacterToFrequency.get(c) > 1) {
                totalScore += 1;
            }
        }
        mapStringToFrequency.put(s, totalScore);
    }
    HashMap<String, Integer> sortByValue = sortByValue(mapStringToFrequency);
    return sortByValue.keySet();
}

private static Map<Character, Integer> wordFrequency(String s) {
    Map<Character, Integer> mapCharacterToFrequency = new HashMap<Character, Integer>();
    for (Character c : s.toCharArray()) {
        if (mapCharacterToFrequency.containsKey(c)) {
            int frequency = mapCharacterToFrequency.get(c);
            frequency += 1;
            mapCharacterToFrequency.replace(c, frequency);
        } else {
            mapCharacterToFrequency.put(c, 1);
        }
    }
    return mapCharacterToFrequency;
}

private static LinkedHashMap<String, Integer> sortByValue(Map<String, Integer> hm) {
    List<Map.Entry<String, Integer>> list = new LinkedList<>(hm.entrySet());
    list.sort(Comparator.comparing(Map.Entry::getValue));
    LinkedHashMap<String, Integer> temp = new LinkedHashMap<>();
    for (Map.Entry<String, Integer> aa : list) {
        temp.put(aa.getKey(), aa.getValue());
    }
    return temp;
}

注意:这是您提供的代码的翻译部分。如果您有任何疑问或需要进一步的帮助,请随时提问。

英文:

try the below code:

public static void main(String[] args){
List&lt;String&gt; list = new ArrayList&lt;String&gt;();
list.add(&quot;apple&quot;);
list.add(&quot;banana&quot;);
list.add(&quot;orange&quot;);
System.out.println(leastFrequentString(list));
}
private static Set&lt;String&gt; leastFrequentString(List&lt;String&gt; list){
Map&lt;String, Integer&gt; mapStringToFrequency = new HashMap&lt;&gt;();
for(String s:list){
Map&lt;Character, Integer&gt; mapCharacterToFrequency =  wordFrequency(s);
int totalScore = 0;
for(Character c:mapCharacterToFrequency.keySet()){
if(mapCharacterToFrequency.get(c)&gt;1){
totalScore+=1;
}
}
mapStringToFrequency.put(s,totalScore);
}
HashMap sortByValue =  sortByValue(mapStringToFrequency);
return sortByValue.keySet();
}
private static Map&lt;Character,Integer&gt; wordFrequency(String s){
Map&lt;Character, Integer&gt; mapCharacterToFrequency = new HashMap&lt;Character, Integer&gt;();
for(Character c: s.toCharArray()){
if(mapCharacterToFrequency.containsKey(c)){
int frequency = mapCharacterToFrequency.get(c);
frequency +=1;
mapCharacterToFrequency.replace(c,frequency);
}else{
mapCharacterToFrequency.put(c,1);
}
}
return mapCharacterToFrequency;
}
private static LinkedHashMap&lt;String, Integer&gt; sortByValue(Map&lt;String, Integer&gt; hm)
{
// Create a list from elements of HashMap
List&lt;Map.Entry&lt;String, Integer&gt; &gt; list =
new LinkedList&lt;&gt;(hm.entrySet());
// Sort the list
list.sort(Comparator.comparing(Map.Entry::getValue));
// put data from sorted list to HashMap
LinkedHashMap&lt;String, Integer&gt; temp = new LinkedHashMap&lt;&gt;();
for (Map.Entry&lt;String, Integer&gt; aa : list) {
temp.put(aa.getKey(), aa.getValue());
}
return temp;
}

答案2

得分: 1

你可以将解决方案分为以下几个步骤:

  • 找到出现最少的字母。在你的水果示例中,这些字母是 l、o、r、g 和 b - 它们的频率都是 1。
  • 计算每个单词中包含了多少个这些字母:apple 中有 1 个,orange 中有 3 个,banana 中有 1 个。
  • 根据这个计数对单词进行排序。

这是你如何找到出现最少的字母。首先通过迭代 elemCount 映射来找到最低频率。然后再次遍历映射,找到具有最低频率的字母:

int lowestFrequency = ...从结果中获取
List<Character> leastFrequentLetters = new ArrayList<>();
for (Map.Entry<Character, Integer> entry : elemCount.entrySet()) {
    if (entry.getValue() == lowestFrequency) {
        leastFrequentLetters.add(entry.getKey());
    }
}

这是你如何计算给定单词中 leastFrequentLetters 中的字母数:

int count = 0;
for (char c: word.toCharArray()) {
    if (leastFrequentLetters.contains(c)) {
        count = count + 1;
    }
}

一旦你有了一种方法来检索或计算每个单词的这个计数,你就可以根据它对单词进行排序。有道理吧?

英文:

You can divide the solution to these steps:

  • Find the least frequent letters. In your fruit example these letters are l, o, r, g, and b - all have frequency 1.
  • Count how many of these letters are contained in each word: apple has 1, orange has 3, banana has 1
  • Sort the words according to that count

This is how you can find the least frequent letters. First find the lowest frequency by iterating the elemCount map. Then iterate over the map again to find the letters with the lowest frequency:

        int lowestFrequency = ...result from
List&lt;Character&gt; leastFrequentLetters = new ArrayList&lt;&gt;();
for (Map.Entry&lt;Character, Integer&gt; entry : elemCount.entrySet()) {
if (entry.getValue() == lowestFrequency) {
leastFrequentLetters.add(entry.getKey());
}
}

This is how you can count how many of the letters of a given word are in leastFrequentLetters:

        int count = 0;
for (char c: word.toCharArray()) {
if (leastFrequentLetters.contains(c)) {
count = count + 1;
}
}

Once you have a method to retrieve or compute this count for each word, you can sort the words by it. Makes sense?

答案3

得分: 1

public class Main {
    public List<String> sortAccordingly(List<String> unsortedList ) {
        List<String> sorted = new ArrayList<>();

        Map<String, Integer> freq = new TreeMap<>();
        Comparator<String> valueCompare = new Comparator<String>() {
            @Override
            public int compare(String s, String t1) {
                return freq.get(s).compareTo(freq.get(t1));
            }
        };
        
        for(String s : unsortedList) {
            Map<Character, Integer> fq = new HashMap<>();
            for (int i = 0; i < s.length(); i++) {
                if (fq.containsKey(s.charAt(i)))
                    fq.replace(s.charAt(i), fq.get(s.charAt(i)) + 1);
                else
                    fq.put(s.charAt(i), 1);
            }
            freq.put(s, Collections.max(fq.values()));
        }
        
        Map<String, Integer> sortedOne = new TreeMap<>(valueCompare);
        sortedOne.putAll(freq);
        sorted.addAll(sortedOne.keySet());
        return sorted;
    }

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("apple");
        list.add("orange");
        list.add("banana");
        System.out.println(new Main().sortAccordingly(list));
    }
}
英文:
public class Main {
public List&lt;String&gt; sortAccordingly(List&lt;String&gt; unsortedList ) {
List&lt;String&gt; sorted=new ArrayList&lt;&gt;();
Map&lt;String,Integer&gt; freq=new TreeMap();
for(String s:unsortedList) {
Map&lt;Character, Integer&gt; fq = new HashMap&lt;&gt;();
for (int i = 0; i &lt; s.length(); i++) {
if (fq.containsKey(s.charAt(i)))
fq.replace(s.charAt(i), fq.get(s.charAt(i)) + 1);
else
fq.put(s.charAt(i), 1);
}
freq.put(s, Collections.max(fq.values()));
}
Map&lt;String,Integer&gt; sortedOne=freq.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(e1,e2)-&gt;e1,LinkedHashMap::new));
sortedOne.putAll(freq);
sorted.addAll(sortedOne.keySet());
return sorted;
}
public static void main(String[] args) {
List &lt;String&gt; list=new ArrayList&lt;&gt;();
list.add(&quot;apple&quot;);
list.add(&quot;orange&quot;);
list.add(&quot;banana&quot;);
System.out.println(new Main().sortAccordingly(list));
}
}

You can use comparator

Comparator&lt;String&gt; valueCompare=new Comparator&lt;String&gt;() {
@Override
public int compare(String s, String t1) {
return freq.get(s).compareTo(freq.get(t1));
}
};

instead of

Map&lt;String,Integer&gt; sortedOne=freq.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(e1,e2)-&gt;e1,LinkedHashMap::new));

after that function will be

public List&lt;String&gt; sortAccordingly(List&lt;String&gt; unsortedList ) {
List&lt;String&gt; sorted=new ArrayList&lt;&gt;();
Map&lt;String,Integer&gt; freq=new TreeMap();
Comparator&lt;String&gt; valueCompare=new Comparator&lt;String&gt;() {
@Override
public int compare(String s, String t1) {
return freq.get(s).compareTo(freq.get(t1));
}
};
for(String s:unsortedList) {
Map&lt;Character, Integer&gt; fq = new HashMap&lt;&gt;();
for (int i = 0; i &lt; s.length(); i++) {
if (fq.containsKey(s.charAt(i)))
fq.replace(s.charAt(i), fq.get(s.charAt(i)) + 1);
else
fq.put(s.charAt(i), 1);
}
freq.put(s, Collections.max(fq.values()));
}
Map&lt;String,Integer&gt; sortedOne=new TreeMap&lt;&gt;(valueCompare);
sortedOne.putAll(freq);
sorted.addAll(sortedOne.keySet());
return sorted;
}

答案4

得分: 0

如果你有一个如你所建议的列表:
[苹果,橙子,香蕉],带有字母频率
a - 5,n - 3,p - 2,e - 2,l- 1,o - 1,r - 1,g - 1,b - 1

从我所看到的,你已经编写了代码来获取这些频率

下一步是:

迭代列表元素 -> 对苹果,橙子和香蕉的每个字母的频率求和 -> 排序! 这样你就可以得到正确的顺序。

希望对你有所帮助。

英文:

If you have a list as you suggested:
[apple, orange, banana] with letter frequency
a - 5, n - 3, p - 2, e - 2, l- 1, o - 1, r - 1, g - 1, b - 1

As I can see you have already written the code to get these frequencies

Next step is to:

iterate over the list elements -> sum frequencies of each letter for apple, orange and banana -> sort! so you can get them in correct order.

Hope this helps.

huangapple
  • 本文由 发表于 2020年4月5日 20:09:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/61042342.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定