c# - 增加具有指定字符模式的唯一字段
问题描述
我正在尝试找到一种方法来增加用户定义的标识符。我写了一些东西来实现我想让代码做的事情,但我非常怀疑这是最好的方法:
字符模式是:
AAA000
AAA999
BAA000
BAA999
BBA000
等等,虽然:
AAA000
AAA999
BAA000
BAA999
CAA000
可以接受。
这是我生成该模式的代码:
int i = 30;
char char1 = 'A';
char char2 = 'A';
char char3 = 'A';
double number = 998;
for (int j = 0; j < i; j++)
{
string id = $"{char1}{char2}{char3}{number.ToString().PadLeft(3, '0')}";
if (number == 999)
{
number = 998;
if (char1 == char2 && char1 == char3 && char1 != 'Z')
{
char1++;
}
else if (char1 > char2 && char2 != 'Z')
{
char2++;
}
else if (char3 != 'Z')
{
char3++;
}
}
else
{
number++;
}
Console.WriteLine(id);
}
为了澄清,我需要构建一个可以获取最新值的函数,例如:
DEF123 依次返回:DEF124
或 DEF999,它将返回 DEG000。
使用马克西米利安的回答,我修改了方法:
static void NextId(string highestId)
{
char startChar1 = highestId[0];
char startChar2 = highestId[1];
char startChar3 = highestId[2];
int startNumber = int.Parse(highestId.Substring(highestId.Length - 3));
int n = 1;
int i = 0;
for (char char1 = startChar1; char1 <= 'Z' && i < n; char1++)
{
for (char char2 = startChar2; char2 <= 'Z' && i < n; char2++)
{
for (char char3 = startChar3; char3 <= 'Z' && i < n; char3++)
{
for (int number = startNumber; number < 1000 && i < n; number++)
{
string id = $"{char1}{char2}{char3}{number.ToString().PadLeft(3, '0')}";
Console.WriteLine(id);
i++;
}
}
}
}
}
这几乎是完美的,除了:
DEZ998 返回 DEZ998,DEZ999 是传入的最高 id,返回 DEZ999。
任何关于实现这一目标的建议都会有很大帮助。
解决方案
我不得不对你的模式做一些假设,但据我了解你的问题,我会使用嵌套循环而不是一个循环来统治它们。
int n = 30;
int i = 0;
for (char char1 = 'A'; char1 <= 'Z' && i < n; char1++)
{
for (char char2 = 'A'; char2 <= 'Z' && i < n; char2++)
{
for (char char3 = 'A'; char3 <= 'Z' && i < n; char3++)
{
for(int number = 0; number < 1000 && i < n; number++)
{
string id = $"{char1}{char2}{char3}{number.ToString().PadLeft(3, '0')}";
Console.WriteLine(id);
i++;
}
}
}
}
这将:
- 将数字从
0
增加到999
- 之后它会将 Char1 加一并从 (1.) 重新开始,直到
Z
达到 - 之后它会将 Char2 加一并从 (2.) 重新开始,直到
Z
达到 - 之后它会将 Char3 加一并从 (3.) 重新开始,直到
Z
达到
n
如果达到最大金额( ),它将在任何时候停止
→ 您将获得最大数量的17575999
可能唯一 ID
更新:
该方法GetNextId(Tuple<char, char, char, int> id)
可以帮助您。它根据前一个 ID 计算下一个 ID。
void GenerateIDs()
{
char char1 = 'B';
char char2 = 'F';
char char3 = 'A';
int number = 159;
int n = 30;
// this one is the current ID
var iterationId = new Tuple<char, char, char, int>(char1, char2, char3, number);
for(int i = 1; i < n; i++)
{
iterationId = GetNextId(iterationId);
Console.WriteLine(IdToString(iterationId));
}
}
/// returns: c1Next, c2Next, c3Next, numberNext
private Tuple<char, char, char, int> GetNextId(Tuple<char, char, char, int> id)
{
var number = id.Item4 + 1;
var c3 = id.Item3;
var c2 = id.Item2;
var c1 = id.Item1;
if(number > 999)
{
number = 0;
c3++;
if(c3 > 'Z')
{
c3 = 'A';
c2++;
if (c2 > 'Z')
{
c2 = 'A';
c1++;
if(c1 > 'Z')
{
throw new IndexOutOfRangeException("Next ID bigger than \"ZZZ999\"");
}
}
}
}
return new Tuple<char, char, char, int>(c1, c2, c3, number);
}
private string IdToString(Tuple<char, char, char, int> id)
{
return $"{id.Item1}{id.Item2}{id.Item3}{id.Item4.ToString().PadLeft(3, '0')}";
}
交替地
您可以只将一个存储int
到数据库并使用这些值0
,17575999
然后计算显示 ID
private string IntToId(int intId)
{
var number = intId % 1000;
intId /= 1000;
char c3 = (char) ('A' + (intId % 26));
intId /= 26;
var c2 = (char) ('A' + (intId % 26));
intId /= 26;
var c1 = (char) ('A' + (intId % 26));
return $"{c1}{c2}{c3}{number.ToString().PadLeft(3, '0')}";
}
private int IdToInt(string id)
{
int c1 = id[0] - 'A';
int c2 = id[1] - 'A';
int c3 = id[2] - 'A';
int number = Int32.Parse(id.Substring(3));
return ((((((c1 * 26) + c2) *26) + c3) * 1000) + number);
}
推荐阅读
- react-native - React Native 组件不重新渲染
- android - 为什么我无法在 android studio 4.1.3 中更改 Textview 或 Button 颜色
- spring-boot - 使用 stomp websocket 从 Spring Boot 向客户端发送数据
- selenium-webdriver - 无法从网络文件夹运行 Selenium MStest
- node.js - 工作线程未在 Node.js 中运行
- python - 使用 Python 中的斯坦福 OpenIE 包装器,出现“文件名或扩展名太长”错误
- c# - 使用 ToString() 从具有嵌套的模型中获取单个字符串
- javascript - 模型与 Sequelize 之间的关联如何?
- python - 在 XGBoost 中为 Score 方法使用自定义指标
- testing - 有什么方法可以测试方法在我的对象上触发吗?