【问题标题】:Counting occurences of a Letter in an infinite String计算无限字符串中字母的出现次数
【发布时间】:2019-04-05 05:39:53
【问题描述】:

我有一个名为s="abcac" 的字符串,它被无限重复了很多次。这意味着s 看起来像:s="abcacabcacabcacabcacabcac...."n 代表s 的子字符串。

例如,如果s="monday"n="10",我们考虑的子字符串将是finalString="mondaymond",因为无限字符串将是"mondaymondaymondaymonday...",而s的前10个字符是"mondaymond"

我正在尝试计算finalString 中字母“a”的出现次数。此代码运行正常,但是当 n>1000000 时程序将无法运行。

此外,如果我将nint 更改为long,则 for 循环在这种情况下将不起作用。

解决这个问题的方法是什么?

public static void main(String[] args){

            String s="abcac";
            int aCount=0;
            int n=1000;
            int j=0;


            char[] sCharArray=s.toCharArray();

            char[] finalString = new char[n];

            for(int i=0;i<n;i++){

                if(j==s.length())
                    j=0;

                finalString[i]=sCharArray[j];
                j++;


            }


            for(int i=0; i<n;i++){
                if(finalString[i]=='a')
                    aCount++;
            }


    System.out.println(aCount);

            }

【问题讨论】:

    标签: java arrays string for-loop character


    【解决方案1】:

    我建议找出基本字符串重复了多少次,并使用此信息计算字母的出现次数,以及最后额外子字符串的出现次数。例如:

    String s = "monday";
    int n = 10;
    String chr = "a";
    
    int baseNum = s.length() - s.replace(chr, "").length();
    int baseCnt = (n / s.length()) * baseNum;
    int index = n % s.length();
    String left = s.substring(0, index);
    int finalCnt = left.length() - left.replace(chr, "").length();
    int totalCnt = baseCnt + finalCnt;
    
    System.out.println("There were " + totalCnt + " letter " + chr + ".");
    

    这里的基本思想是效率。我们实际上不需要创建和使用任意长度的字符串,因为我们知道它只是重复相同的子字符串。相反,我们可以只计算子字符串中出现的次数,然后根据子字符串重复的次数来预测总数。

    【讨论】:

    • 非常感谢。这是我正在寻找的纯“数学”算法!非常高效,没有循环或重复数组。
    • 实际上这个解决方案不包括@yasserkabbout 在他的问题中提到的n 类型更改为long 的情况。
    • @ETO 我已将算法修改为 long。数学方法更好......你怎么看?
    • @ETO 你是对的,但是String#length() 返回一个整数,而不是一个长整数,所以理论上来说,无限字符串不能有一个不适合整数的长度。无论如何,这个问题更多的是关于算法而不是你提出的观点。
    • @yasserkabbout 好吧,这三种解决方案在底层都有相同的数学方法。理论上s 的长度可以是一个非常大的数字(最大为 MAX_INT)。我的建议是在这种特殊情况下避免使用.substring.replace,因为在我的情况下,它们的总复杂度远远超过 O(n)。
    【解决方案2】:

    正如其他答案中已经指出的那样,您不需要构建最终字符串。

    这是我的解决方案:

    public static void main(String[] args){
        String s = "abcacas";
        long n = 1000000;
    
        long count = getCount(s, n, 'a');
        System.out.println(count);
    }
    
    private long getCount(String str, long n, char c) {
        int length = str.length();
    
        long repeats = n / length;
        long reminder = n % length;
    
        long count = 0;
        for (int i = 0; i < length; i++) {
            if (str.charAt(i) == c) {
                count += repeats;
                if (i < reminder) {
                    count++;
                }
            }
        }
        return count;
    }
    

    【讨论】:

    • 感谢您的贡献。我检查了我的 IDE 上的代码,但是它不起作用,因为 n 类型是整数。但是,我发现在您将变量类型更改为 long 后它现在可以工作了。
    【解决方案3】:

    您不需要构造最终字符串。您只需计算s 字符串中“a”(或任何您想要的)的出现次数,并计算此s 重复的次数。毕竟,在提醒中计算“a”的出现次数。

    long countInS = // count all occurances of 'a'
    long repeats = n / s.length;
    long reminder = n % s.length;
    String sReminder = s.substring(reminder);
    long countInReminder = // count all occurances of 'a' in sReminder 
    long count = repeats * countInS + countInReminder;
    

    无需浪费内存

    【讨论】:

      【解决方案4】:

      我们可以通过在计算出现次数之前计算余数来进一步优化,并像这样使用它

      import java.util.Scanner;
      public class Main
      {
          public static void main(String[] args){
          Scanner ip=new Scanner(System.in);
          String s=ip.next();
          int n=ip.nextInt();
          int res=0;
          int c=0,len=s.length(),cnt=0;
          for(;cnt<len;cnt++){
          if(s.charAt(cnt)=='a')
          c++;
          if(n%len!=0&&cnt==(n%len)-1)
          res=c;
          }
          int mul=n/len;
          System.out.println((mul*c)+res);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-04
        • 2016-01-23
        • 1970-01-01
        • 1970-01-01
        • 2020-07-23
        • 2021-06-11
        • 2015-12-01
        • 2022-01-07
        相关资源
        最近更新 更多