【发布时间】:2016-05-02 08:45:32
【问题描述】:
我有一个bool[],我想从该原始数组生成该数组的版本/场景并将其保存到list<bool[]>。
如果数组看起来像{true,true,false,true,true,true}。这个想法是,如果bool[0] 和bool[1] 都为真而bool[2] 为假。我想创建一个场景,其中 bool[0] 和 bool[1] 为假,bool[2] 为真,并将该场景添加到我的列表中。我目前正在 for 循环中执行此操作,以检查数组中的每个插槽中的模式 {true,true,false} 或 {false, true,true}。目标是找到我在数组中拥有尽可能少的bool = true 元素并返回该数组的场景。
我试图用蛮力来做这件事,但它太慢了(有时是几分钟)。我希望它适用的语言是 C#。有没有比蛮力更有效的方法来创建场景?
我用于生成场景的代码:
class Program
{
public static List<bool[]> alternativs = new List<bool[]>();
public static int arrayCount = 23;
public static int tempCount = 0;
static void Main(string[] args)
{
//this works fast
bool[] easyInput = new bool[23] { true, true, false, false, false, false, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false };
//this takes forever
bool[] hardInput = new bool[23] { true, true, false, true, true, false, true, true, false, true, true, false, true, true, false, true, true, false, true, true, false, true, true };
alternativs.Add(easyInput);
while (alternativs.Count > 0)
{
for (int i = 0; i < 21; i++)
{
if (alternativs[0][i] == true && alternativs[0][i + 1] == true && alternativs[0][i + 2] == false)
{
bool[] temp = new bool[23];
bool[] temp3 = new bool[23];
Array.Copy(alternativs[0], temp, 23);
Array.Copy(temp, temp3, 23);
Array.Reverse(temp3);
temp[i] = false;
temp[i + 1] = false;
temp[i + 2] = true;
if (!alternativs.Contains(temp) && !alternativs.Contains(temp3))
{
alternativs.Add(temp);
}
}
if (alternativs[0][i] == false && alternativs[0][i + 1] == true && alternativs[0][i + 2] == true)
{
bool[] temp2 = new bool[23];
bool[] temp4 = new bool[23];
Array.Copy(alternativs[0], temp2, 23);
Array.Copy(temp2, temp4, 23);
temp2[i] = true;
temp2[i + 1] = false;
temp2[i + 2] = false;
if (!alternativs.Contains(temp2) && !alternativs.Contains(temp4))
{
alternativs.Add(temp2);
}
}
}
tempCount = 0;
for (int j = 0; j < 23; j++)
{
if (alternativs[0][j] == true)
tempCount++;
}
if (tempCount < arrayCount)
{
arrayCount = tempCount;
}
alternativs.RemoveAt(0);
}
Console.WriteLine(arrayCount);
}
}
经过一些修改,代码如下所示:
class Program
{
public static List<string> alternativs = new List<string>();
public static int arrayCount = 23;
public static int tempCount = 0;
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
//this works fast
//string easyInput = "11000011110000000000000";
//this takes forever
string hardInput = "11011011011011011011011";
string xtra = "00101100011010000000000";
string TmpVal = "";
string RevVal = "";
alternativs.Add(xtra);
while (alternativs.Count > 0)
{
if (alternativs[0].Contains("110"))
{
TmpVal = alternativs[0];
TmpVal = TmpVal.Replace("110", "001");
RevVal = string.Concat(Enumerable.Reverse(TmpVal)); //String Reverse
if (!alternativs.Any(xs => xs.SequenceEqual(TmpVal)) && !alternativs.Any(xs => xs.SequenceEqual(RevVal)))
{
alternativs.Add(TmpVal);
}
}
if (alternativs[0].Contains("011"))
{
TmpVal = alternativs[0];
TmpVal = TmpVal.Replace("011", "100");
RevVal = string.Concat(Enumerable.Reverse(TmpVal)); //String Reverse
if (!alternativs.Any(xs => xs.SequenceEqual(TmpVal)) && !alternativs.Any(xs => xs.SequenceEqual(RevVal)))
{
alternativs.Add(TmpVal);
}
}
tempCount = alternativs[0].Count(x => x == '1');
if (tempCount < arrayCount)
{
arrayCount = tempCount;
}
alternativs.RemoveAt(0);
}
Console.WriteLine(arrayCount);
sw.Stop();
Console.WriteLine(sw.Elapsed);
Console.ReadLine();
}
}
根据要求,我将完成从原始数组到包含尽可能少的{true} 的数组的过程。在下面的示例中,我将使用1 表示true 和0 表示false。
我将使用一个简单的示例并展示它是如何手动完成的:
这是输入数组{0110100101011},我们称之为myInput。
第 1 步:我选择 1 表单 myInput[1] 并跳过 myInput[2] 并登陆 myInput[3]。这会将myIput[1] 转换为0,将myInput[2] 转换为0,将myInput[3] 转换为1。
此移动的结果数组是{0001100101011}。
如果我将myInput[2] 移动到myInput[1] 上,myInput[2] 将不得不跳转到myInput[0] 并导致像{1000100101011} 这样的数组。这将无法删除myInput[4] 处的1,因为它现在被0 包围。
让我们继续第一个正确的举动,导致{0001100101011}。我要做的下一步是myInput[3] 到myInut[5]。给我们这个结果{0000010101011}。然后myInput[12] 到myInput[10]。结果{0000010101100}。 myInput[10] 到 myInput[8]。结果{0000010110000}。 myInput[8] 到 myInput[6]。结果{0000011000000}。最后,myInput[6] 到 myInput[4]。结果{0000100000000}。
给我们一个1 数组{0001100101011} 的结果,因为没有更多可能的移动。
由于我编写的程序必须检查所有不同的动作,并且不能说将 1 从 myInput[2] 移动到 myInput[0] 开始是不明智的,所以我必须让程序测试 att不同的动作并将它们存储到我的列表alternativs。这会产生大量场景,这就是减慢我的程序的原因。
我仍然没有设法解决这个问题。
【问题讨论】:
-
也许我有点睡着了,但我不明白你的问题。您想获得原始数组的组合或排列吗?也许如果你向我们展示你的代码,它会让一切变得更清晰
-
是的,请向我们展示您的代码。我希望能够复制粘贴并运行。
-
我在尝试创建场景的地方添加了一些代码。我想从原始数组中获得一个新的修改数组。我正在将所有生成的场景添加到一个列表中,并且该列表正在快速增长!
-
@Billy - 代码无法编译。
alternativs的定义是什么? -
我仍然没有得到确切的使用,但如果花费的时间太长,我认为最好预先计算所有的可能性,然后根据你的实际情况你只需要跳转到之前计算的最佳可能性