如何摆脱清单中的循环号 [英] How do I get rid of circular numbers in my list
问题描述
好的,我知道这段代码是粗糙的,周围都是一片混乱,但是我不是程序员,所以请多多包涵。我有列出一堆数字的这段代码,但我希望它不列出数字的任何循环副本。
Okay, I know that this code is crude, and all around a messy, but I am no programmer, so bear with me. I have this code that lists a bunch of numbers, but I want it to not list any circular copies of the numbers.
例如,如果数字111262在我的列表中,则我不想列出112621、126211、262111、621112或211126。
抱歉,该数字不能在列表中。
对于 true 示例,如果数字111252在我的列表中,则我不想列出112521、125211、252111、521112或211125。
For a true example, if the number 111252 is on my list, I don't want 112521, 125211, 252111, 521112, or 211125 to be listed.
感谢您的帮助!
namespace Toric_Classes
{
class Program
{
static void Main(string[] args)
{
int number_of_perms=0;
bool badsubsum1;
bool badsubsum2;
int subsum1 = 0;
int subsum2 = 0;
int sum = 0;
int class_length=6;
int[] toric_class=new int[class_length];
// The nested for loops scroll through every possible number of length class_length, where each digit can have a value of 1,2,..., or class_length-1
// Each number is looked at as an array, and is not stored anywhere, only printed if it satisfies certain conditions
for(int i1=1; i1<class_length; i1++)
{
toric_class[0] = i1;
for (int i2 = 1; i2 < class_length; i2++)
{
toric_class[1] = i2;
for (int i3 = 1; i3 < class_length; i3++)
{
toric_class[2] = i3;
for (int i4 = 1; i4 < class_length; i4++)
{
toric_class[3] = i4;
for (int i5 = 1; i5 < class_length; i5++)
{
toric_class[4] = i5;
for (int i6 = 1; i6 < class_length; i6++)
{
badsubsum1 = false;
badsubsum2 = false;
toric_class[5] = i6;
// Find the value of the sum of the digits of our array.
// We only want numbers that have a total digit sum being a multiple of class_length
for (int k = 0; k < class_length; k++)
{
sum += toric_class[k];
}
// The follwong two nested loops find the value of every contiguous subsum of our number, but not the total subsum.
// We *do not* want any subsum to be a multiple of class_length.
// That is, if our number is, say, 121342, we want to find 1+2, 1+2+1, 1+2+1+3, 1+2+1+3+4, 2+1, 2+1+3, 2+1+3+4, 2+1+3+4+2, 1+3, 1+3+4, 1+3+4+2, 3+4, 3+4+2, and 4+2
// The following checks 1+2, 1+2+1, 1+2+1+3, 1+2+1+3+4, 2+1, 2+1+3, 2+1+3+4, 1+3, 1+3+4, and 3+4
for (int i = 0; i < class_length - 1; i++)
{
for (int j = i + 1; j < class_length - 1; j++)
{
for (int k = i; k < j; k++)
{
subsum1 += toric_class[k];
}
if (subsum1 % class_length == 0)
{
badsubsum1 = true;
break;
}
subsum1 = 0;
}
}
// The following checks 2+1, 2+1+3, 2+1+3+4, 2+1+3+4+2, 1+3, 1+3+4, 1+3+4+2, 3+4, 3+4+2, and 4+2
for (int i = 1; i < class_length; i++)
{
for (int j = i + 1; j < class_length; j++)
{
for (int k = i; k < j; k++)
{
subsum2 += toric_class[k];
}
if (subsum2 % class_length == 0)
{
badsubsum2 = true;
break;
}
subsum2 = 0;
}
}
// We only want numbers that satisfies the following conditions
if (sum % class_length == 0 && badsubsum1 == false && badsubsum2 == false)
{
foreach (var item in toric_class)
{
Console.Write(item.ToString());
}
Console.Write(Environment.NewLine);
number_of_perms++;
}
sum = 0;
subsum1 = 0;
subsum2 = 0;
}
}
}
}
}
}
Console.WriteLine("Number of Permuatations: "+number_of_perms);
Console.Read();
}
}
}
编辑
为了澄清,我正在创建一个满足特定条件且长度为n的所有数字的列表。考虑数字d1d2 ... dn,其中每个di是我们数字的数字。每个di的值可以为1,2,...,n。如果满足以下条件,则我们的数字在列表中
To clarify, I am creating a list of all numbers with length n that satisfy certain conditions. Consider the number d1d2...dn, where each di is a digit of our number. Each di may have value 1,2,...,n. Our number is in the list if it satisfies the following
-
所有数字的总和为n的倍数,即,
The sum of all the digits is a multiple of n, that is,
d1 + d2 + ... + dn = 0 mod n
d1+d2+...+dn = 0 mod n
每个连续的子和除了总和之外,数字不是n的倍数,也就是说,如果i!= 1和j!= n,则
Every contiguous subsum of the digits is not a multiple of n, aside from the total sum, that is, if i !=1 and j != n, then
di + d(i + 1)+ ... + dj!= 0 mod n
di+d(i+1)+...+dj != 0 mod n
我应该再次提及,数字并不严格使用数字中的0-9。它可以取1到n之间的任何值。在我的代码中,我使用n = 6的情况。
I should mention again that a "number" does not strictly use the numbers 0-9 in its digits. It may take any value between 1 and n. In my code, I am using the case where n=6.
该代码通过创建长度为 class_length $ c $的数组来工作c>(在上面的代码中,我使用
class_length = 6
)。我们首先有6个嵌套的for循环,这些循环仅将值分配给数组 toric_class
。对于,第一个
分配
toric_class [0]
,对于 >分配
toric_class [1]
,依此类推。在第一遍中,我们生成数组 111111
,然后生成 111112
,直到 111115
,然后是 111121
,依此类推。因此,从本质上讲,我们正在查看不包含0的所有十六进制数。一旦达到在我们的数组中,我们检查数组 toric_class
并检查其值以确保它满足上述条件。如果是这样,我们只需将数组打印成一行,然后继续。
The code works by creating an array of length class_length
(in the code above, I use class_length=6
). We first have 6 nested for loops that simply assign values to the array toric_class
. The first for
assigns toric_class[0]
, the second for
assigns toric_class[1]
, and so on. In the first go around, we are generating the array 111111
, then 111112
, up to 111115
, then 111121
, etc. So essentially, we are looking at all heximal numbers that do not include 0. Once we reach our sixth value in our array, we check the array toric_class
and check its values to ensure that it satisfies the above conditions. If it does, we simply print the array in a line, and move on.
推荐答案
这是我简单高效的方法,应该对您的代码进行最小的更改。它需要共享的字符串列表 var strList = new List< string>();
来存储使用的数字。然后这部分:
Here is my easy and inefficient way that should work with minimal changes to your code. It requires shared string list var strList = new List<string>();
to store the used numbers. Then this part:
foreach (var item in toric_class)
{
Console.Write(item.ToString());
}
Console.Write(Environment.NewLine);
number_of_perms++;
成为类似这样的东西:
string strItem = " " + string.Join(" ", toric_class) + " "; // Example: int[] {1, 12, 123} becomes " 1 12 123 "
if (!strList.Any(str => str.Contains(strItem))) // Example: if " 1 12 123 1 12 123 " contains " 1 12 123 "
{
Console.WriteLine(strItem);
strItem += strItem.Substring(1); // double the string, but keep only one space between them
strList.Add(strItem);
}
number_of_perms++; // not sure if this should be in the if statement
这个想法是,例如字符串 1 1 1 2 5 2 1 1 1 2 5 2
包含数字的所有循环副本{1、1、1、2、5、2}
。我使用字符串作为一种懒惰的方式来检查数组是否包含子数组,但是您可以使用类似的方法将使用过的数字的副本存储在数组列表中。 new List< int []>()
并检查列表中的任何数组是否为当前数组的循环副本,甚至更好的是 HashSet< int []>()
类似于@slavanap的答案。
The idea is that for example the string " 1 1 1 2 5 2 1 1 1 2 5 2 "
contains all circular copies of the numbers {1, 1, 1, 2, 5, 2}
. I used string as a lazy way to check if array contains sub-array, but you can use similar approach to store copy of the used numbers in a list of arrays new List<int[]>()
and check if any of the arrays in the list is circular copy of the current array, or even better HashSet<int[]>()
approach similar to @slavanap's answer.
我的答案的第一个版本是最简单的,但仅适用于单个数字项的数组。
The first version of my answer was the easiest, but it works only with array of single digit items.
List
与数组几乎相同( new List< string>()
而不是 new string []
),但可以轻松,高效地向其中添加项目。例如, {1,2} .Add(3)
变为 {1,2,3}
。
List
is almost the same as array (new List<string>()
instead of new string[]
), but makes it much easier and efficient to add items to it. For example {1,2}.Add(3)
becomes {1,2,3}
.
str => str.Contains(strItem)
是接受参数 str
并返回结果 str.Contains( strItem)
。然后,该功能将传递给 .Any
LINQ扩展,所以
str => str.Contains(strItem)
is shortcut for a function that accepts parameter str
and returns the result of str.Contains(strItem)
. That "function" is then passed to the .Any
LINQ extension, so
strList.Any(str => str.Contains(strItem))
是类似这样的快捷方式:
is shortcut for something like this:
foreach(string str in strList)
{
if (str.Contains(strItem))
{
return true;
}
}
return false;
这篇关于如何摆脱清单中的循环号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!