2016-10-20 2 views
-2

Итак, мне нужно написать программу с использованием циклов, которая берет строку и подсчитывает, что и сколько букв появляется в этой строке. (строка «лучшее масло» будет печатать «b появляется 2 раза, e появляется 3 раза,« (пробел) появляется 1 раз и т. д.). Хотя я понимаю идею и концепцию, лежащую в основе этого задания, грубый.Возникли проблемы с циклами

Мой вложенные для цикла, где проблемы идут от, я полагаю. то, что я написал только петли один раз (я думаю), и просто показывает первый символ и говорит, что есть только один из этого символа.

Редактировать: Не рекомендуется использовать карту или массивы. Я в порядке с их использованием, если это единственный способ, но они не были охвачены в моем классе, поэтому я стараюсь их избегать. это (что я нашел) использует карту или массив.

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); 
       } 

} 
+0

Вы пробовали отлаживать? – shmosel

+0

Ваша попытка сделать подсчет и распечатку результатов одновременно. Отделите эти два вопроса. Сначала запишите символы, а затем после этого выведите информацию. – NineBerry

+0

Возможный дубликат [count occistence of element in array] (http://stackoverflow.com/questions/13923442/count-occurance-of-element-in-array) – Enfyve

ответ

1

Сначала вам нужно будет сканировать всю строку и сохранить отсчетов каждого символа. Позже вы можете просто распечатать подсчеты.

Алгоритм 1:

  1. Используйте HashMap для хранения символа, как ключ и его количество в качестве значения. (Если вы новичок в Java, вы можете прочитать на HashMaps.)

  2. Каждый раз, когда вы читаете символ в ваш цикл, проверьте, если он присутствует в HashMap. Если да, то увеличиваем счетчик на 1. Else добавить новые символы на карту со счетом 1.

Печать: Просто итерацию на вашем 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) 
} 
+0

Есть ли способ без использования HashMap или массива? Прошу прощения, я забыл добавить его в исходный вопрос. – Conf3tti

+0

да, вы можете сделать это без использования HashMap или массивов. Я обновлю свое решение. –

+0

Выполнение этого без массива занимает больше времени. – Charles

0

Я хотел бы сделать следующее. Создайте HashMap, который отслеживает, какие уникальные символы находятся в строке и количество для каждого символа.

Вам нужно только один раз перебрать строку и поместить каждый символ в HashMap. если characer находится на карте, скопируйте целочисленное число на карте, иначе добавьте 1 к карте для этого символа. Распечатайте карту с помощью toString(), чтобы получить результат. Все это можно сделать примерно в 4 строках кода.

+0

Есть ли способ без использования HashMap или массива? Прошу прощения, я забыл добавить его в исходный вопрос. – Conf3tti

+0

Вы повторили то, что сказал Ренука. Зачем? – Charles

+0

Если вы посмотрите на отметки времени, вы увидите, что я действительно не повторил, что сказал Ренука, но Ренука - это скорее быстрый типер. Я пришел через несколько минут после другого поста. – adamM

0

Единственное, что делается в вашей вложенной цикл со следующими

C = S.Шара (CNT)

является установка c полукокса на значение первой буквы (т.е. индекс 0 строки) снова и снова и снова, пока вы петельные через бурильную п^2 раз. Другими словами, вы не увеличиваете счетчик cnt внутри циклов for.

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

Обратите внимание, что это может быть расширена за счет включения заглавных букв, но и для демонстративных целей, только строчные буквы обрабатываются в коде выше.

EDIT: В то время как OP было спросить, если это было возможно сделать это без массива, я бы не рекомендовал, например. Это решение будет иметь сложную временную сложность и повторить количество символов (если только массив не используется для отслеживания видимых символов, что противоречит цели). Таким образом, вышеупомянутое решение является наилучшим способом сделать это за разумное время (линейное) при ограниченном потреблении пространства.

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; 
} 

Он должен работать, простите за мой английский, потому что я итальянский

+0

Цикл 'for (boolean a: view)' не нужен по двум причинам: 1) логические массивы инициализируются по умолчанию «false», а 2) 'a' является копией и не будет изменять действительный элемент в массив. – Charles

+0

Вы правы, и я не знал, что массив булевых элементов был инициализирован false. –

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

Пожалуйста, в следующий раз используйте функцию поиска, прежде чем отправлять новый вопрос.

Смежные вопросы