打印所有唯一的数字号码
问题:打印所有只有唯一数字的号码。 输入:N = 15 输出:1 2 3 4 5 6 7 8 9 10 12 13 14 15打印所有唯一的数字号码
此处11没有包括在内,因为它有1两次,同样的方法123,456 ..也是有效的,但121 1344无效,因为同一位数字不止一次。
我正在运行1- n循环并检查每个数字。 我使用散列图来确定数字的唯一性。
有没有更好的解决上述问题的方法。
这是我如何消除具有重复字符的数字。
Console.Write("Input:");
int number = int.Parse(Console.ReadLine());
List<int> numbers = new List<int>();
List<int> acceptedNumbers = new List<int>();
for (int i = 1; i <= number; i++)
{
numbers.Add(i);
}
foreach (var num in numbers)
{
bool rejected = false;
char[] numChars = num.ToString().ToCharArray();
foreach (var numChar in numChars)
{
if (numChars.Where(n => n == numChar).Count() > 1)
{
rejected = true;
}
}
if (!rejected)
{
acceptedNumbers.Add(num);
}
}
acceptedNumbers.ForEach(n => Console.Write($"{n} "));
Console.Read();
您可以使用LINQ,将数字转换为字符串,并检查字符串的长度是否等于不同的charchters的数量。
for (int i = 1; i < n; i++){
if (i.ToString().Length == i.ToString().Distinct().Count())
Console.Out.Write(i + " ");
}
为什么在循环中使用LINQ时? –
OP没有发布任何示例代码,我认为要检查的数字不是“存储”在任何地方,而是从1运行到输入数字。 –
我的想法:
- 从0执行循环到n
- 对于10每批(如从0到9,10至19,230至239 ..),挑数字与最后一个分开。这些数字映射到往往会被跳过的计数器。休息一切都要被排出。例如:对于第12x批次,选择1 & 2,现在我们知道必须跳过第1位和第2位的数字,并且全部都是可以接受的,因此不需要为它们执行任何处理。
- 将上述数字以排序的方式保存在arrayList中并将指针保留在索引0处。让我们称之为'ptr'。在遍历该批处理时,检查每批的count(从0移到9)是否等于数组[ptr]。如果否,则发出号码。否则,跳过它并执行ptr ++。
- 当您正在执行第2步时,检查是否有任何数字重复。如果是,跳过10
整批有没有字符串操作发生的,所以应该在效率
我不知道带来的,但类似的东西..
List<int> numbers = new List<int>(){};
numbers =numbers.Where(p=>validCheck(p)==true).ToList();
static bool validCheck(int n)
{
return (n.ToString().Length==n.ToString().Disctinct().Count());
}
做得很好。 :) –
我很高兴,它的工作。 :) @LeonelSarmiento –
哪里也会直接接受该方法。 ... .Where(validCheck)...它已经返回一个布尔值,所以与true比较并不会执行任何操作。 – moreON
字符串是一个IEnumerable - 所以你可以使用LINQ语句来解决问题:
Numbers.Where(N => N.ToString().Distinct().Count() == N.ToString().Length);
查询被检查多少CH您的号码字符串中的字符不同,并将此数字与总字符数相联系。
这里是整个代码打印出所有不同数字,直到20:
List<int> Numbers = new List<int>();
for (int i = 1; i <= 20; i++)
{
Numbers.Add(i);
}
IEnumerable<int> AcceptedNumbers = Numbers.Where(N => N.ToString().Distinct().Count() == N.ToString().Length);
foreach (int AcceptedNumber in AcceptedNumbers)
{
Console.WriteLine(AcceptedNumber);
}
另一种解决方案是使用整数除法和模数(没有编号,以串转换)。您可以使用以下方法验证数字的唯一性(假设digits
是int
数组有10个元素)。
public static bool IsUnique(int num) {
int[] digits = new int[10];
num = Math.Abs(num);
while (num > 0) {
int r = num % 10;
num /= 10;
digits[r] ++;
if (digits[r] > 1) {
return false;
}
}
return true;
}
...为什么通过'数字'?为什么不把它声明为局部变量?另外,如果'num'为负值会发生什么? –
'数字'被传递来防止每次调用函数时分配内存。我更新了处理负数的方法(在'while'循环之前采用'absolute') – putu
不,我的意思是我想这就是你想要避免的,我只是不确定“设置”成本在一般情况下是值得的。现在我很好奇JIT是否可以识别情况并反复使用本地阵列... –
因为在那里你有开始,有多少你想要的种子它的半有用的库函数。
public static IEnumerable<int> UniqueDigits(int start, int count)
{
for (var i = start; i < (start + count); i++)
{
var s = i.ToString();
if (s.Distinct().Count() == s.Length)
{
yield return i;
}
}
}
然后
UniqueDigits(0,15).ToList().ForEach(Console.WriteLine);
或
foreach (var digit in UniqueDigits(100,50))
{
Console.WriteLine(digit);
}
只有9 * 9! /(10 - n)!具有n
数字的唯一数字号码。对于较大的n
,您可能需要一个下一个字典算法以避免不必要的迭代。 (例如,只有544320 7,独特的数字号码,但你的程序将需要通过近10万个号码进行迭代产生它们!)
这是我在下一个字典程序尝试对一组n-unique-digit
号码(如n > 1
):
(1) From left to right, start with the digits 10, then ascend from 2.
For example, the first 4-digit number would be 1023.
(2) Increment the right-most digit that can be incremented to the next available
higher digit unused by digits to its left. Ascend to the right of the
incremented digit with the rest of the available digits, starting with lowest.
Examples: 1023 -> 1024 (4 is unused by the digits left of 3)
^
9786 -> 9801 (8 is unused be the digits left of 7)
^
9658 -> 9670 (7 is unused by the digits left of 5)
^
何不[在C++广义置换(无重复)](http://stackoverflow.com/a/30498154/2521214)的使用和直接作为增量生成输出数字。 .. – Spektre
什么是n的上限? – MBo
@MBo值n