for循环遇到问题

时间:2016-10-20 22:46:51

标签: java

所以,我需要使用循环来编写程序,该循环接受一个字符串并计算该字符串中出现的字母数和数量。 (字符串"更好的黄油"打印" b出现2次,e出现3次,''(空格)出现1次,依此类推)。虽然我理解这个任务背后的想法和概念,但实际上把它拉下来一直很粗糙。

我认为,我的嵌套for循环是问题的来源。我只写了一次循环(我想),只显示第一个字符,并说只有其中一个字符。

编辑最好不使用地图或数组。如果它是唯一的方法,我可以使用它们,但是我们的课程没有覆盖它们,所以我试图避开它们。其他每个类似的问题(我发现)都使用Map或数组。

import java.util.Scanner;

class myString{
    String s;

    myString() {
        s = "";
    }
    void setMyString(String s) {
        this.s = s;
    }
    String getMyString() {
        return s;
    }
    String countChar(String s){
        s = s.toUpperCase();
        int cnt = 0;
        char c = s.charAt(cnt);
        for (int i = 0; i <= s.length(); i++)
            for (int j = 0; j <= s.length(); j++)  //problem child here
                c = s.charAt(cnt);
                cnt++;
                if (cnt == 1)
                    System.out.println(c+" appears "+cnt+" time in "+s);
                else
                    System.out.println(c+" appears "+cnt+" times in "+s);
                return "for";  //this is here to prevent complaint from the below end bracket.
    }
}

public class RepeatedCharacters {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s;

        System.out.println("Enter a sentence: ");
        s = in.nextLine();


        myString myS = new myString();
     //   System.out.println(myS.getMyString());
     //   System.out.println(myS.countChar());
        myS.countChar(s);
                }

}

6 个答案:

答案 0 :(得分:1)

  

首先,您需要扫描整个字符串并存储   每个字符的数量。稍后您可以打印计数。

     

算法1:

  1.   

    使用HashMap将字符存储为键,将其计数值作为值。 (如果您是Java新手,可能需要阅读   包含HashMap。)

  2.   

    每次在for循环中读取一个字符时,请检查它是否存在于HashMap中。如果是,则将计数增加1.否则   使用计数1向地图添加新字符。

  3.   

    印刷:   只需迭代你的HashMap并打印出角色和   他们各自的数量。

         

    您的代码问题:您正在尝试尽快打印计数   读一个角色。但是这个角色可能会在以后再出现   串。所以你需要跟踪你已经拥有的角色   读取。

    算法2:

    String countChar(String s){
        has_processed = []
        for i = 0 to n
            cnt = 0
            if s.charAt(i) has been processed
                continue;
            for j = i+1 to n
                if (s.charAt(i) == s.charAt(j))
                    cnt++
                    add s.charAt(i) to has_processed array
            print the count of s.charAt(i)
    }
    

答案 1 :(得分:1)

使用频率数组以线性时间得到答案。

/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        String s = "better butter";

        int freq[] = new int[26];

        int i;
        for (i = 0; i < s.length(); i++) {
            if (s.charAt(i) >= 'a' && s.charAt(i) <= 'z')
                freq[s.charAt(i)-'a']++;
        }

        for (i = 0; i < freq.length; i++) {
            if (freq[i] == 0) continue;
            System.out.println((char)(i+'a') + " appears " + freq[i] + " times" );
        }
    }
}

Ideone Link

请注意,这可以扩展为包含大写字母,但出于演示目的,上述代码中只处理小写字母。

编辑 :虽然OP确实询问是否可以在没有阵列的情况下执行此操作,但我建议不要这样做。该解决方案将具有可怕的时间复杂度和重复字符计数(除非使用数组来跟踪所看到的字符,这与目标相反)。因此,上述解决方案是在合理的时间内(线性)和空间消耗有限的最佳方式。

答案 2 :(得分:0)

我会做以下事情。创建一个HashMap,它跟踪字符串中的哪些唯一字符以及每个字符的计数。

您只需迭代字符串一次,并将每个字符放入HashMap。如果characer在地图中,则在地图中对整数计数进行icrement,否则在该地图的地图上添加1。使用toString()打印出地图以获得结果。整个过程可以在大约4行代码中完成。

答案 3 :(得分:0)

使用以下

在嵌套for循环中完成的唯一操作
  

c = s.charAt(cnt)

c char设置为第一个字母的值(即字符串的索引0),一遍又一遍,直到你循环遍历字符串n ^ 2次。换句话说,您根本没有在for循环中递增cnt计数器。

答案 4 :(得分:0)

这是我的countChar(String s)版本

boolean countChar(String s) {
    if(s==null) return false;
    s = s.toUpperCase();
    //view[x] will means that the characted in position x has been just read
    boolean[] view = new boolean[s.length()];

    /*
    The main idea is:
    foreach character c = s.charAt(x) in the string s, I have a boolean value view[x] which say if I have already examinated c.
    If c has not been examinated yet, I search for other characters equals to c in the rest of the string.
    When I found other characters equals to c, I mark it as view and I increment count with count++.
    */
    for (int i = 0; i < s.length(); i++) {
        if (!view[i]) {
            char tmp = s.charAt(i);
            int count = 0;
            for (int j = i; j < s.length(); j++) {
                if (!view[j] && s.charAt(j) == tmp) {
                    count++;
                    view[j] = true;
                }
            }
            System.out.println("There were " + count + " " + tmp);
        }
    }
    return true;
}

这应该有用,请原谅我的英语,因为我是意大利人

答案 5 :(得分:0)

建议:尝试为变量使用有意义的名称;它会在你的职业生涯中帮助你很多。类名也应始终以大写字母开头。

虽然它在性能方面不是最快的解决方案,但最简单的解决方案应该是:

import java.util.HashMap;
import java.util.Map;
...
Map<String, Integer> freq = new HashMap<String, Integer>();
...
int count = freq.containsKey(word) ? freq.get(word) : 0;
freq.put(word, count + 1);

来源:Most efficient way to increment a Map value in Java

请在下次发布新问题之前使用搜索功能。