我正在使用SAP Idocs,它们包含可包含成本中心参考范围的段。范围以字符串的开始和结束值给出。要在我的数据库中存储这些值,我需要生成这些值之间存在的所有可能组合。
字符串是字母数字,例如start:D98C1
和end:D9AZ3
。单个char序列是从0到9的第一个数字,然后是从A到Z的字母。扩展需要生成开始和结束之间的所有可能组合,比如说开始:A1
到结束:CA
将包含值A1
至A9
,AA
至AZ
,B0
至B9
,BA
至BZ
,C0
至C9
和CA
。
我完全坚持这一点,并且非常感谢关于如何实现这一点的一些指示。
编辑:
作为一个人,我会从找到不同的开始和结束字符串之间的部分开始。我能做到这一点,这很容易。因此,对于上面的示例,那将是D9
。然后我会一次查看一个字符串的起始字符串的变量部分,并从字符串末尾改变所有字符,遍历所有可能的字符,直到我到达结束字符串中的相应字符。
我只是坚持实施。
我开始时有这样的事情:
readonly static char[] values = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToArray();
static void Main(string[] args)
{
string from = "D3A0";
string to = "D3AC";
string root = new string(from.TakeWhile((c, i) => to.Length >= i && to[i] == c).ToArray());
string from1 = from.Substring(root.Length);
string to1 = to.Substring(root.Length);
var output = new List<string>();
for (int i = from1.Length - 1; i == 0; i--)
{
char startChar = from1[i];
char endChar = to1[i];
var remainingValues = values.SkipWhile(v => v != startChar)
.TakeWhile(v => v != endChar)
.ToList();
foreach (char v in remainingValues)
{
string currentValue = from1.Remove(i) + v;
output.Add(currentValue);
}
if (output.Contains(to1))
{
break;
}
}
foreach (var s in output.Select(o => root + o))
{
Console.WriteLine(s);
}
}
但它没有提供所有组合。
答案 0 :(得分:5)
答案 1 :(得分:1)
这样的事情怎么样:
public static string Next(string current)
{
if (current.EndsWith("Z"))
return Next(current.Substring(0, current.Length - 1)) + "0";
if (current.EndsWith("9"))
return current.Substring(0, current.Length - 1) + "A";
return current.Substring(0, current.Length - 1) + (char) (current[current.Length-1] + 1);
}
然后像这样调用它
var value = "A1";
while (value != "CB")
{
Console.WriteLine(value);
value = Next(value);
}
答案 2 :(得分:0)
也许是这样的:
private static string values = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static void Main()
{
string from = "Y5";
string to = "ZZ";
var counter = from;
var output = new List<string>();
while(counter != to) {
counter = Increment(counter);
output.Add(counter);
}
Console.WriteLine(string.Join(Environment.NewLine, output));
}
private static string Increment(string counter){
if(counter.Length < 1) {
counter = values[0] + counter;
}
var lastChar = counter[counter.Length - 1];
var lastCharIndex = values.IndexOf(lastChar);
if(lastCharIndex == -1)
{
throw new InvalidOperationException("Sequence contains an invalid character: " + lastChar);
}
var nextCharIndex = values.IndexOf(lastChar) + 1;
if(nextCharIndex >= values.Length)
{
return Increment(counter.Substring(0, counter.Length - 1)) + values[0];
}
return counter.Substring(0, counter.Length - 1) + values[nextCharIndex];
}
应该使用任何组合/值的顺序。
答案 3 :(得分:0)
我敲了下面的内容 - 作为第一个努力 - 将值设置为可用的字符选项。这就是人类如何做到这一点。它没有效率,它并不光彩,但它确实起到了作用。
$connectionString = "Data Source=YourServer;Initial Catalog=tempdb;Integrated Security=SSPI;Application Name=PerformanceTestScript";
$guidSetupScript = @"
CREATE TABLE dbo.Example (
StaticId uniqueidentifier NOT NULL,
UserId uniqueidentifier NULL,
UserGroupId uniqueidentifier NULL,
CompanyId uniqueidentifier NULL,
CompanyGroupId uniqueidentifier NULL,
CompanyAccessUnitRole uniqueidentifier NULL,
PRIMARY KEY CLUSTERED (StaticId)
);
WITH
t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
,t1k AS (SELECT 0 AS n FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c)
,t10m AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS num FROM t1k AS a CROSS JOIN t1k AS b CROSS JOIN t1k AS c CROSS JOIN t10 AS d)
INSERT INTO dbo.Example WITH(TABLOCKX) (
StaticId
, UserId
, UserGroupId
, CompanyId
, CompanyGroupId
, CompanyAccessUnitRole
)
SELECT
NEWID()
, NEWID()
, NEWID()
, NEWID()
, NEWID()
, NEWID()
FROM t10m
WHERE num <= 3000000;
"@
$intSetupScript = @"
CREATE TABLE dbo.Example (
StaticId int NOT NULL,
UserId int NULL,
UserGroupId int NULL,
CompanyId int NULL,
CompanyGroupId int NULL,
CompanyAccessUnitRole int NULL,
PRIMARY KEY CLUSTERED (StaticId)
);
WITH
t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
,t1k AS (SELECT 0 AS n FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c)
,t10m AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS num FROM t1k AS a CROSS JOIN t1k AS b CROSS JOIN t1k AS c CROSS JOIN t10 AS d)
INSERT INTO dbo.Example WITH(TABLOCKX) (
StaticId
, UserId
, UserGroupId
, CompanyId
, CompanyGroupId
, CompanyAccessUnitRole
)
SELECT
num
, num
, num
, num
, num
, num
FROM t10m
WHERE num <= 3000000;
"@
try
{
$values = [System.Array]::CreateInstance([System.Object], 6)
$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
$command = New-Object System.Data.SqlClient.SqlCommand
$command.CommandTimeout = 0
$connection.Open()
$command.Connection = $connection
#Guid setup
$command.CommandText = "IF OBJECT_ID(N'dbo.Example') IS NOT NULL DROP TABLE dbo.Example;"
[void]$command.ExecuteNonQuery()
$command.CommandText = $guidSetupScript
[void]$command.ExecuteNonQuery()
#guid test
$testSw = [System.Diagnostics.StopWatch]::StartNew()
Write-Host "Starting Guid test."
$command.CommandText = "SELECT * FROM dbo.Example;"
$reader = $command.ExecuteReader()
while($reader.Read()) {
$values = $reader.GetValues($values)
}
$reader.Close()
$testSw.Stop()
Write-Host "Guid test duration was $($testSw.Elapsed.ToString())"
#int setup
$command.CommandText = "IF OBJECT_ID(N'dbo.Example') IS NOT NULL DROP TABLE dbo.Example;"
[void]$command.ExecuteNonQuery()
$command.CommandText = $intSetupScript
[void]$command.ExecuteNonQuery()
#int test
$testSw = [System.Diagnostics.StopWatch]::StartNew()
Write-Host "Starting int test."
$command.CommandText = "SELECT * FROM dbo.Example;"
$reader = $command.ExecuteReader()
while($reader.Read()) {
$values = $reader.GetValues($values)
}
$reader.Close()
$testSw.Stop()
Write-Host "Int test duration was $($testSw.Elapsed.ToString())"
$connedtion.Close()
}
catch [Exception]
{
throw
}