我想使用Quicksort解决以下问题。
我在一个数组中有 n 字符串,其中每个字符串都保证为正正数,没有前导零和1到10 ^ 6之间的数字。我使用带有BigInteger
结构的常规快速排序来做到这一点,但是我有很多超时情况导致我认为我需要优化我的比较方式并从string[]
中删除解析到BigInteger[]
并返回string[]
,所以我决定按原样排序。这是我的代码:
static void swap(string[] array, int first, int second)
{
var temp = array[first];
array[first] = array[second];
array[second] = temp;
}
static void quickSort(string[] array, int left, int right)
{
if (left >= right) return;
var pivot = array[(left + right) / 2];
var index = partition(array, left, right, pivot);
quickSort(array, left, index - 1);
quickSort(array, index, right);
}
static int partition(string[] array, int left, int right, string pivot)
{
while(left <= right)
{
while (left < array.Length && !array[left].IsBigger(pivot)) left++;
while (right < array.Length && array[right].IsBigger(pivot)) right--;
if (left <= right)
{
swap(array, left, right);
left++;
right--;
}
}
return left;
}
static bool IsBigger(this string a, string b)
{
if (a.Length < b.Length) return false;
else if(a.Length > b.Length) return true;
for (int i = 0; i < a.Length; i++)
{
if (a[i] > b[i]) return true;
else return false;
}
return false;
}
但是,当IsBigger
函数的输入非常小[ "31415926535897932384626433832795", "1", "3", "10", "3", "5" ]
时,我会在quickSort(unsorted, 0, unsorted.Length - 1);
函数中出现异常,而我似乎无法尝试原因。
没有任何有趣的时刻叫做quicksort - 我就是这样做的RuntimeHelpers.EnsureSufficientExecutionStack();
IsBigger
中调用Function MySQL-nonQuery($server, $user, $pass, $database, $sql){
try{ #set up My SQL connection
[void][System.Reflection.Assembly]::LoadWithPartialName("MySql.Data")
$connectionString = "server=" + $server + ";port=3306;uid=" + $user + ";pwd=" + $pass + ";database="+$database + ";AllowUserVariables=True"
$connection = New-Object MySql.Data.MySqlClient.MySqlConnection
$connection.ConnectionString = $ConnectionString
$connection.Open()
}
catch{
$Error[0]
}
#set up command
$updateCOD = New-Object MySql.Data.MySqlClient.MySqlCommand($sql, $connection)
$updateCOD.CommandText
$updateCOD.ExecuteNonQuery()
$connection.Close()
}
但是没有工作,一切看起来都不错也答案 0 :(得分:2)
IsBigger似乎存在问题
“1234” .IsBigger( “1235”) 和 “1235”.IsBigger(“1234”)
都返回false。
应该删除循环中的else子句。
答案 1 :(得分:1)
问题是我很傻到相信 x&gt; y ==!(x&lt; y)当它真的应该是 x&gt; y == x&lt; = y 。注意离散数学家的类别。
这让我介绍另一种辅助方法
static bool IsLessThan(this string a, string b)
=> a.Equals(b) ? false : !a.IsBigger(b);
最终将分区方法更改为
static int partition(string[] array, int left, int right, string pivot)
{
while (left <= right)
{
while (array[left].IsLessThan(pivot)) left++;
while (array[right].IsBigger(pivot)) right--;
if (left <= right)
{
swap(array, left, right);
left++;
right--;
}
}
return left;
}
答案 2 :(得分:0)
出于某种原因,这种情况永远不会发生
if (left >= right) return;
你永远不会回来。因此,你永远地递归并溢出你的筹码。使用您的调试器找出您正确的原因&gt;左
答案 3 :(得分:0)
可以尝试这样的方法,并将“IsBigger”扩展方法调整为您想要的内容:
using System;
namespace ConsoleApp1
{
class Program
{
static void swap(string[] array, int first, int second)
{
var temp = array[first];
array[first] = array[second];
array[second] = temp;
}
static void quickSort(string[] array, int left, int right)
{
int i = left, j = right;
var pivot = array[(left + right) / 2];
while (i <= j)
{
while (array[i].IsBigger(pivot))
{
i++;
}
while (array[j].IsBigger(pivot))
{
j--;
}
if (i <= j)
{
// Swap
swap(array, i, j);
i++;
j--;
}
}
// Recursive calls
if (left < j)
{
quickSort(array, left, j);
}
if (i < right)
{
quickSort(array, i, right);
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var array = new[] { "31415926535897932384626433832795", "1", "3", "10", "3", "5" };
// Print the unsorted array
for (int i = 0; i < array.Length; i++)
{
Console.Write(array[i] + " ");
}
Console.WriteLine();
quickSort(array, 0, array.Length - 1);
// Print the sorted array
for (int i = 0; i < array.Length; i++)
{
Console.Write(array[i] + " ");
}
Console.WriteLine();
Console.WriteLine("Done!");
Console.ReadLine();
}
}
public static class StringExtension
{
public static bool IsBigger(this string a, string b)
{
if (a.Length < b.Length) return false;
else if (a.Length > b.Length) return true;
for (int i = 0; i < a.Length; i++)
{
if (a[i] > b[i]) return true;
return false;
}
return false;
}
}
}