【问题标题】:Sorting arrays with if else statements使用 if else 语句对数组进行排序
【发布时间】:2017-10-23 19:03:00
【问题描述】:

所以,我正在使用 java 进行一个项目,在该项目中我必须输入一个字符串并计算字符串中字符的频率。然后,我必须将字符分为四类:文本、空格、数字和符号。我正在寻找一种方法来做到这一点。为了计算字符串中的频率,这是我目前所拥有的:

    char[] charArray = userSort.toCharArray();
        char tempChar;
        for (int i = 0; i < charArray.length; i++) {
            for (int j = 0; j < charArray.length; j++) {
                if (charArray[i] < charArray[j]) {
                    tempChar = charArray[i];
                    charArray[i] = charArray[j];
                    charArray[j] = tempChar;]

我也有关于如何使用 if-else 语句对这些语句进行排序和打印的概念。

 int whiteSpace = 0;
            int textual = 0;
            int numerical = 0;
            int symbols = 0;

        if() {
            whiteSpace++;
        }

        else if (){
            textual++;
            }

        else if (){
            numerical++;
        }
        else {
            symbols++;
        }
            System.out.println("Textual Character count: " + textual);
            System.out.println("Numerical Character count: " + numerical);
            System.out.println("Whitespace Character count: " + whiteSpace);
            System.out.println("Symbol character count: " + symbols);

我只是不确定我使用 if else 语句将其保留在特定类别中。我也不确定如何将两个代码组合在一起。任何帮助表示赞赏,谢谢。

另外,我不能使用内置 java 排序函数或类似的东西。

【问题讨论】:

  • 您的排序算法(类似于冒泡排序)不正确。既然需要统计,为什么还要对数据进行排序?
  • 我不确定这是否会有所帮助,但您可以将它们存储在不同的数组中并分别对每个数组进行排序。
  • 对于假设为 ascii 输入的类别的提示 (c==' ')('a'
  • @davidbuzatto 这是冒泡排序!我的代码分为三个部分:一个按字母顺序排序,一个按频率排序,最后,我必须将所有内容分类。我只是打算继续使用相同的方法来计数。这是个坏主意吗?
  • 看看我更新的答案。你的冒泡排序有点问题。我的第二个代码片段将解决您的问题。

标签: java arrays sorting ascii


【解决方案1】:

这里是您的起点,使用地图存储计数:

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;

public class TestCount {

    public static void main( String[] args ) {

        String myString = "abc abc abc abc aaabbbccc 0000 *&% a";
        int whiteSpace = 0;
        int textual = 0;
        int numerical = 0;
        int symbols = 0;

        char[] data = myString.toCharArray();
        Arrays.sort( data );

        Map<Character, Integer> countMap = new LinkedHashMap<>();
        for ( char c : data ) {
            if ( countMap.containsKey( c ) ) {
                countMap.put( c, countMap.get( c ) + 1 );
            } else {
                countMap.put( c, 1 );
            }
        }

        for ( Map.Entry<Character, Integer> e : countMap.entrySet() ) {

            char key = e.getKey();
            System.out.printf( "%c -> %d occurences\n", e.getKey(), e.getValue() );

            if ( ( key >= 'a' && key <= 'z' ) || ( key >= 'A' && key <= 'Z' ) ) {
                textual += e.getValue();
            } else if ( key >= '0' && key <= '9' ) {
                numerical += e.getValue();
            } else if ( key == ' ' ) {
                whiteSpace += e.getValue();
            } else {
                symbols += e.getValue();
            }

        }

        System.out.printf( "%d are textual characters\n", textual );
        System.out.printf( "%d are numerical characters\n", numerical );
        System.out.printf( "%d are whitespace characters\n", whiteSpace );
        System.out.printf( "%d are symbol characters\n", symbols );

    }

}

编辑:

这是一个简单而肮脏的解决方案,没有使用排序和地图等内置功能。它将字符代码(表示字符的整数)映射到数组位置。由于字符是有序的,数据数组的最后一个字符是代码较大的字符,将是最后一个有效的数组位置。

public class TestCount {

    public static void main( String[] args ) {

        String myString = "abc abc abc abc aaabbbccc 0000 *&% a";
        int whiteSpace = 0;
        int textual = 0;
        int numerical = 0;
        int symbols = 0;

        char[] data = myString.toCharArray();
        mySort( data );

        // a counting array. it will waste a lot of space, but it will work
        int[] countArray = new int[ (int) data[data.length-1] + 1 ];

        for ( char c : data ) {
            countArray[ (int) c ]++;
        }

        char lastChar = '\0';
        for ( char c : data ) {

            if ( c != lastChar ) {
                System.out.printf( "%c -> %d occurences\n", c, countArray[ (int) c ] );
            }

            if ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) ) {
                textual++;
            } else if ( c >= '0' && c <= '9' ) {
                numerical++;
            } else if ( c == ' ' ) {
                whiteSpace++;
            } else {
                symbols++;
            }

            lastChar = c;

        }

        System.out.printf( "%d are textual characters\n", textual );
        System.out.printf( "%d are numerical characters\n", numerical );
        System.out.printf( "%d are whitespace characters\n", whiteSpace );
        System.out.printf( "%d are symbol characters\n", symbols );

    }

    public static void mySort( char[] array ) {
        for ( int i = 0; i < array.length; i++ ) {
            for ( int j = 0; j < array.length-1; j++ ) {
                if ( array[j] > array[j+1] ) {
                    char t = array[j];
                    array[j] = array[j+1];
                    array[j+1] = t;
                }
            }
        }
    }

}

编辑 2: 一种更节省空间的方法:

public class TestCount {

    public static void main( String[] args ) {

        String myString = "abc abc abc abc aaabbbccc 0000 *&% a";
        int whiteSpace = 0;
        int textual = 0;
        int numerical = 0;
        int symbols = 0;

        char[] data = myString.toCharArray();
        mySort( data );

        // a counting array. it will waste a lot of space, but it will work
        int[] countArray = new int[ (int) data[data.length-1] + 1 - (int) data[0]  ];

        for ( char c : data ) {
            countArray[ map(data[0], c) ]++;
        }

        char lastChar = '\0';
        for ( char c : data ) {

            if ( c != lastChar ) {
                System.out.printf( "%c -> %d occurence(s)\n", c, countArray[ map(data[0], c)  ] );
            }

            if ( c >= 'A' && c <= 'z' ) {
                textual++;
            } else if ( c >= '0' && c <= '9' ) {
                numerical++;
            } else if ( c == ' ' ) {
                whiteSpace++;
            } else {
                symbols++;
            }

            lastChar = c;

        }

        System.out.printf( "%d are textual characters\n", textual );
        System.out.printf( "%d are numerical characters\n", numerical );
        System.out.printf( "%d are whitespace characters\n", whiteSpace );
        System.out.printf( "%d are symbol characters\n", symbols );

    }

    public static int map( char leftBoundary, char charToMap ) {
        return (int) charToMap - (int) leftBoundary;
    }

    public static void mySort( char[] array ) {
        for ( int i = 0; i < array.length; i++ ) {
            for ( int j = 0; j < array.length-1; j++ ) {
                if ( array[j] > array[j+1] ) {
                    char t = array[j];
                    array[j] = array[j+1];
                    array[j+1] = t;
                }
            }
        }
    }

}

【讨论】:

  • 谢谢!这很有帮助,但遗憾的是,我被禁止使用它。这正是我在被告知无法使用此方法之前开始我的项目的方式。
  • @AraniqueBrown 你不能使用地图?
  • 不,不允许使用地图。从字面上看,我不得不从头开始,因为我使用了它们。
  • 谢谢!这正是我想要的方法。
  • @AraniqueBrown 欢迎您。如果答案对您来说足够了,请考虑将其标记为正确答案和/或投票。如果您需要更有效的空间方法,则需要更改数据映射到数组的方式。
【解决方案2】:

您可以使用 HashMap 来计算字符的频率,其中字符本身就是键,并在找到该值时递增该值。你当前的算法是 O(n^2) 因为你在另一个里面有一个 for 但是如果你在 O(n) 上使用 hashmap dicrease

例如。

    String text = "Hello world";
    HashMap<Character, Integer> chars = new HashMap<>();
    for(int i = 0; i < text.length(); i++){

        //Get the current char
        char letter = text.charAt(i);

        //If the hashmap has the key is a new ocurrence
        if(chars.containsKey(letter)){
            chars.put(letter, chars.get(letter) + 1);
        }else{
            chars.put(letter, 1);
        }
    }

然后你必须对键进行分类。

    for(char tempChar : chars.keySet()){
        //Sort the current char by type
    }

您有两次时间复杂度为 O(n) 的迭代。所以最后是O(n),没有O(n^2)。

您当前的算法不适用于大量数据。

检查这个以了解原因。 Big-O Algorithm Complexity

问候。

【讨论】:

  • 所以?为什么您想要一个不是最好的解决方案?这是一种方法。
【解决方案3】:

它应该像遍历你的 charArray 然后使用这些 if/else 一样简单。 为了知道一个元素是什么,你应该使用 ascii 分配表https://www.dotnetperls.com/ascii-java

   for (int i = 0; i < charArray.length; i++) {
       int asciiValue = int(charValue);

       if(asciiValue == 11 || (asciiValue >= 28 && asciiValue <= 31) {
           whiteSpace++;
       }
   }

对文本(65 - 90 和 97 - 122)、数字(48 - 57)和符号应用相同

【讨论】:

  • 谢谢!这很有帮助。我可以问为什么代码中的 asciiValue == 1 吗?如果值在 28 到 31 之间,不应该只是下半场吗?
  • 是我的一个错字 - 我的意思是输入 11 -> 这也是一个空格
  • 如果我能提供帮助,如果您能接受我的解决方案,我会很高兴 - 否则反馈或进一步的问题会很好:D
  • 我现在明白了。谢谢!
  • 那太棒了 :) 你能点击勾号接受答案吗?
猜你喜欢
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
  • 2016-05-26
  • 2019-05-13
  • 1970-01-01
  • 2015-05-16
  • 2011-05-28
  • 1970-01-01
相关资源
最近更新 更多