【问题标题】:Count the number of times a character appears in a contiguous manner in a string计算一个字符在字符串中以连续方式出现的次数
【发布时间】:2023-03-04 22:18:02
【问题描述】:

我是 Java 新手。我正在尝试打印字符串中存在的字符及其计数。只有当旁边出现相同的字符时,计数才会增加。

例如:

I/O : Sssgs

O/P : S1s2g1s1

计算每个字符的出现次数会给出完整计数的计数,而不管字符是否彼此相邻。篡改 i & j 循环会导致 OutOfBounds 错误。

      //ch[] is the String converted to a character array.
     //count[] is an array to store count of the characters      

    //Checks if present char and next char are same and increments count
    for(int i=0;i<ch.length;i++)    
    {
        count[i]=0;
        for(int j=0;j<ch.length;j++)
        {
            if(ch[i]==ch[j])
            {
                count[i]++;
            }
        }
    }

    //Prints Distinct char
    for(int i=0;i<ch.length;i++)
    {
        int j;
        for(j=0;j<i;j++)
        {
            if(ch[i]==ch[j])
            {
                break;
            }
        }

        if(i==j)
        {
            System.out.print(ch[i]+" "+count[i]);
        }
    }

输入是 > HelloWorld

预期的输出应该是 > H1 e1 l2 o1 W1 o1 r1 l1 d1

【问题讨论】:

  • 我会使用StringBuiler。 1)遍历字符串,2)将字符添加到构建器并增加计数器 3.a)如果前一个字符等于当前字符,则增加计数器,3.b)如果不相等,附加计数器并重置它 -> 在 2 处继续。
  • 重新开始,用纸和笔“编程”。只需要知道前面的字符(char)和它出现了多少次(int),不是吗?或当前字符 (char) 以及它跟随的次数 (int)。解决方案很短。
  • 您的意思是“连续”(彼此相邻)吗? “传染性”意味着可能会传播,就像疾病一样。
  • 请阅读“如何创建minimal reproducible example”。然后使用edit 链接改进您的问题(不要通过 cmets 添加更多信息)。否则我们无法回答您的问题并为您提供帮助。你给出了预期的输出,省略了实际的输出。当你有异常时,包括异常堆栈跟踪。
  • 除此之外,看看:stackoverflow.com/questions/5554734/…

标签: java arrays frequency


【解决方案1】:

这是一个简单的解决方案,它不使用任何额外的数组,而是在下一个不同的字符时直接打印计数的字符

char prevChar = ch[0];
int count = 1;
for (int i = 1; i < ch.length; i++) {
  if (ch[i] != prevChar) {
    System.out.printf("%c%d ", prevChar, count);
    count = 1;
    prevChar = ch[i];
  } else {
    count++;
  }
}
System.out.printf("%c%d ", prevChar, count); 

【讨论】:

  • 这对我来说似乎是完美的解决方案,应该是公认的答案。或者,可以将结果写入 StringBuilder 或 ArrayList.
【解决方案2】:

我讨厌这个解决方案,但我猜你是因为需要而使用 char[]。如果不是强制性的,我建议您按照 Lino 的建议使用 StringBuilder

char blankChar = " ".charAt(0);
if (stringInput == null || "".equals(stringInput)) {
    System.out.println("Empty input");
}
char[] ch = stringInput.toCharArray();
char lastChar = ch[0];
int numAppearanceslastChar = 0;
for (char element : ch) {
    if (element == blankChar) {
        continue;
    }
    if (lastChar == element) {
        numAppearanceslastChar++;
    } else {
        System.out.print(lastChar+""+numAppearanceslastChar+" ");
        lastChar = element;
        numAppearanceslastChar = 1;
    }
}
System.out.println(lastChar+""+numAppearanceslastChar+" ");

输出:H1 e1 l2 o1 w1 o1 r1 l1 d1

解释:整个单词只读取一次(注意你在 for 循环中做了 3 次)并将最后读取的字符与新字符进行比较。如果它们匹配,则增加该字符的出现次数。如果不是,则打印它们并将新字符设置为最后一次读取。 当您结束阅读单词时,打印最后一个读取的字符。

永远记得保持简单!并清理(如果收到 null 或空,您将在此代码中得到一个 nullPointer,只需将其写在那里以指出它)。

【讨论】:

  • 你为什么要引入一个字符串,只是为了把 char[] 去掉?另外, char blankChar = " ".charAt(0) 背后的想法是什么——而不是仅仅做 char blankChar = ' '?
  • 我使用字符串只是因为我用字符串而不是 char[] 测试它,而且我更习惯使用字符串。确实,我会做类似 Lino 的事情,但使用 char[] 来解决。使用 charAt(0) 和 not '' 之间的想法是相同的,用于处理字符串而不是字符。 :)
【解决方案3】:

我想出了这个:

public static String count(String in) {
    if (in == null || in.isEmpty()) {
        return in;
    }
    int length = in.length();
    if (length == 1) {
        return in + '1';
    }
    StringBuilder out = new StringBuilder(length << 1);

    char previous = in.charAt(0);
    int count = 1;
    for (int i = 1; i < length; i++) {
        char current = in.charAt(i);
        if (previous == current) {
            count++;
        } else {
            out.append(previous).append(count);
            previous = current;
            count = 1;
        }
    }
    return out.append(previous).append(count).toString();
}

处理空字符串和空字符串。以及带有length == 1 的字符串(即string + 1)。

此解决方案也不需要创建额外的 char[] 数组,因为它与 charAt 一起使用

【讨论】:

    【解决方案4】:

    我刚刚对您的代码进行了一些更正,下面是它的样子:

    public static void main(String[] args) {
        String s = "Sssgs";
        char[] ch = s.toCharArray();
        int[] count = new int[20];
    
           for(int i=0;i<ch.length;i++)    
            {
                count[i]=0;
                for(int j=i;j<ch.length;j++)
                {
                    if(ch[i]==ch[j])
                    {
                        count[i]++;
                    } else {
                        break;
                    }
                }
            }
    
            //Prints Distinct char
            for(int i=0;i<ch.length;i += count[i])
            {
                System.out.print(ch[i] + "" +count[i]);
            }
    }
    

    当我刚刚读取字符及其出现次数然后在迭代中跳转该数字时,大多数更改都发生在 Prints Distincts 中。它让我停在下一个不同的字符上

    “Sssgs”的输出是“S1s2g1s1”,“HelloWorld”的输出是“H1e1l2o1W1o1r1l1d1”

    【讨论】:

    • 这解决了我的问题,谢谢。我对 Distinct 的 for 循环感到困惑。 i += count[i] 到底是做什么的?
    • 它检查字母的出现次数并跳转该数字。因此,如果您有“sssS”,那么对于 i=0('s' 字符)计数 = 3 因为有三个 's' 所以下一个 'i' 将是 0 + 3 = 3 所以它会跳转到字母 'S'并检查它的出现是 1 然后 i = 3 + 1 = 4 不小于 ch.length 所以循环完成
    猜你喜欢
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多