【问题标题】:Counting up with no repeating digits in a number在数字中没有重复数字的情况下进行计数
【发布时间】:2016-08-14 23:26:39
【问题描述】:

我正在尝试优化我的程序计数器。这取决于数字的大小(从 3 到 10 位,没有重复) - 例如012, 013,214 等我的第一个解决方案是 for 循环,如下所示:

private void sample() {
        int[] varValue = new int[3];
        innerloop: for (int a = 0; a < 10; a++) {
            for (int b = 0; b < 10; b++) {
                if (a == b)
                    continue;
                for (int c = 0; c < 10; c++) {
                    if (c == b)
                        continue;
                    if (c == a)
                        continue;
                    varValue[0] = a;
                    varValue[1] = b;
                    varValue[2] = c;

                    int EqOne = varValue[0] * 100 + varValue[1] * 10 + varValue[2];

                    if (EqOne == 432) {
                        System.out.println(varValue[0]);
                        System.out.println(varValue[1]);
                        System.out.println(varValue[2]);
                        break innerloop;
                    }

                }
            }

        }
    }

或 10 位数字 (https://gist.github.com/TrollerN/6a0e470c539c57fd4cd73086cf6eb41b)

然后我可以将这些 a, b, c 添加到 int[] 或 ArrayList 并使用它。没关系,但是有 10 个不同的数字,它用 if 语句替换了 10 个 for 循环 + 我必须创建 8 种不同的方法 - 每个位数一个。

我还尝试创建 10 位 (0,1,2,3,4,5,6,7,8,9) 的 ArrayList,将其随机播放并返回 3-10 位,但它可能永远不会- 9-10 位数字的结束循环。

我的下一个“好”想法(不,老实说,这是迄今为止最愚蠢的一个:D)是针对每种情况将组合的 ArrayList 保存到文件中,然后加载所需的一个并通过它找到解决方案。

我正在考虑创建一些方法来获取位数(“所以它知道它需要多少个循环”)和/或最后一个解决方案,所以它知道要开始。

编辑: 我已经用示例方法修改了这个问题。当然 int EqOne 和 If 语句要复杂得多,但它在技术上显示了我想要实现的目标 - 至少我希望:P

我一直在寻找一种方法,它可以根据需要创建尽可能多的循环和大数组/数组列表?

【问题讨论】:

  • 问题是……?
  • 你到底想达到什么目的?
  • 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:minimal reproducible exampleHow to Ask
  • 你没有说清楚这段代码应该做什么,这使得无法回答。如果我猜的话,我会说您似乎正在尝试输出多个数字的不同排列?例如。 1+2 可能是 12 或 21。使用嵌套的 for 循环,您不知道需要多少级别,一种解决方案可能是递归。这取决于你真正想要达到的目标。
  • 获取我可以使用的 int[] 或 ArrayList 值,这将不断变化并寻找解决方案。

标签: java performance for-loop arraylist counter


【解决方案1】:

由于不允许重复数字,因此很难直接生成您要查找的列表。我认为最简单的方法是首先按字典顺序获取所有 n 长度组合,然后获取每个组合的所有排列。也就是说,对于n = 2 的情况,您将生成"01", "02", ... , "78", "79", "89",然后将获得每个的所有排列。

这是我整理的一个快速程序,它可以让你得到你想要的:

public static List<String> getCombinations (String digits, int n) {

  List<String> out = new ArrayList<String>();
  for ( int k = 0; k < digits.length (); ++k ) {
    if ( n == 1 )
      out.add (digits.charAt (k) + "");
    else {
      for ( String s : getCombinations (digits.substring (k + 1), n - 1) ) {
        out.add (digits.charAt (k) + s);
      }
    }
  }

  return out;
}


public static List<String> getPermutations (String s, String prefix) {

  List<String> out = new ArrayList<String>();

  if ( s.length () == 1 ) {
    out.add (prefix + s);
  }
  else {
    for ( int i = 0; i < s.length (); ++i ) {
      out.addAll (getPermutations (prefix + s.charAt (i), s.substring (0, i) + s.substring (i + 1)));
    }
  }

  return out;
}


public static List<String> getPermutations (List<String> combinations) {
  List<String> out = new ArrayList<String>();
  for ( String s : combinations )
    out.addAll (getPermutations (s, ""));

  return out;
}


public static void main (String[] args) {

  List<String> combinations = getCombinations ("0123456789", 3);

  List<String> permutations = getPermutations (combinations);

  for ( String s : permutations ) {
    System.out.println (s);
  }

}

【讨论】:

    【解决方案2】:

    假设您想要 数字 给定长度,而不是字符串,一种方法是使用 boolean[10] 记住当前正在使用的数字,以便可以快速跳过它们。

    然后将数字保留在一个数组中,并像普通数字一样增加最后一位数字。当它翻转时,您增加倒数第二个数字,依此类推,将尾随数字重置为未使用的数字。

    示例:如果当前号码是1097,则如下所示:

    Digits  In Use               Description
    1097    0 1 _ _ _ _ _ 7 _ 9
    1097    0 1 _ _ _ _ _ _ _ 9  Clear in-use of last digit
    1098    0 1 _ _ _ _ _ _ _ 9  Increment last digit
    1098    0 1 _ _ _ _ _ _ 8 9  Mark in-use
    =======================================================
    1098    0 1 _ _ _ _ _ _ _ 9  Clear in-use of last digit
    1099    0 1 _ _ _ _ _ _ _ 9  Increment last digit, but it's in use
    109?    0 1 _ _ _ _ _ _ _ 9  Rollover, so go to previous digit
    109?    0 1 _ _ _ _ _ _ _ _  Clear in-use
    10??    0 1 _ _ _ _ _ _ _ _  Rollover, so go to previous digit
    10??    _ 1 _ _ _ _ _ _ _ _  Clear in-use
    11??    _ 1 _ _ _ _ _ _ _ _  Increment digit, but it's in use
    12??    _ 1 _ _ _ _ _ _ _ _  Increment digit
    12??    _ 1 2 _ _ _ _ _ _ _  Mark in-use
    120?    0 1 2 _ _ _ _ _ _ _  Set to first unused digit, and mark in-use
    1203    0 1 2 3 _ _ _ _ _ _  Set to first unused digit, and mark in-use
    =======================================================
    

    如您所见,逻辑使其从1097 变为1098 再到1203

    这是其中的逻辑。运行示例见IDEONE

    final class UniqueDigitCounter {
        private int[]     digits;
        private boolean[] inUse = new boolean[10];
        public UniqueDigitCounter(int digitCount) {
            if (digitCount < 1 || digitCount > 10)
                throw new IllegalArgumentException("Invalid digit count: " + digitCount);
            this.digits = new int[digitCount];
            for (int i = 0; i < digitCount; i++) {
                this.digits[i] = i;
                this.inUse[i] = true;
            }
        }
        public long next() {
            if (this.digits == null)
                return -1; // end of sequence
            long value = 0;
            for (int i = 0; i < this.digits.length; i++)
                value = value * 10 + this.digits[i];
            for (int i = this.digits.length - 1; ; i--) {
                if (i == -1) {
                    this.digits = null; // end of sequence
                    break;
                }
                int digit = this.digits[i];
                this.inUse[digit] = false;
                if ((digit = nextDigit(digit + 1)) != -1) {
                    this.digits[i] = digit;
                    while (++i < this.digits.length)
                        this.digits[i] = nextDigit(0);
                    break;
                }
            }
            return value;
        }
        private int nextDigit(int minDigit) {
            for (int digit = minDigit; digit < 10; digit++)
                if (! this.inUse[digit]) {
                    this.inUse[digit] = true;
                    return digit;
                }
            return -1;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-12
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      • 2019-02-16
      • 2018-09-23
      • 2023-01-30
      • 1970-01-01
      相关资源
      最近更新 更多