假设有一个n个用户的队列,您的任务是为他们分配一个用户名。该系统以以下方式工作。每个用户都喜欢以字符串s的形式进行的首选登录,该登录仅由小写字母和数字组成。用户名按以下顺序分配:s,s0,s1,s2….s11…。意味着首先检查s是否可用,如果已被占用,则对其进行检查;如果s0已被空闲,则对其进行检查;是否已被占用,则对s1,进行此类检查……如果将用户名分配给一个用户,则该用户将被其他用户占用。在他排队之后。
例子:
Input: names[] = {abc, bcd}
Output: user_names[] = {abc bcd}
Input: names[] = {abc, bcd, abc}
Output: user_names[] = {abc bcd abc0}
Input : names[] = {geek, geek0, geek1, geek}
Output : user_names[] = {geek geek0 geek1 geek2}
For first user geek is free so it is assigned to him similarly for the second and third user but for fourth user geek is not free so we will check geek0 but it is also not free then we will go for geek1 but it is also not free then we will check geek2 it is free so it is assigned to him.
我们使用Trie解决了这个问题。我们不使用具有26个子代的普通Trie,而是使用一个Trie,其中的节点具有36个子代26个字母(az)和10个从(0-9)的数字。除此之外,Trie的每个节点都将具有bool变量,当插入在该节点结尾的字符串时,布尔变量将变为true,也将有一个int变量,也可以称其为add,它的初始值为-1,并且假设该字符串为geek并且此int变量等于-1,则意味着我们将直接返回首次请求的geek,但假设它是12,则意味着字符串geek,geek0…..geek12已存在于Trie中。
脚步
第1步:维护Trie,如上所述。
步骤2:对于每个给定名称,检查用户给定的字符串是否不在Trie中,然后返回相同的字符串,否则从i = add + 1开始(上面讨论了add),然后开始检查是否将i与输入字符串连接起来是否存在于Trie中(如果不存在),则将其返回并设置add = i并将其插入到Trie中,否则递增i
假设字符串是geek且i = 5检查geek5是否在Trie中,如果不存在则返回geek5 set add for geek = 5在grie中插入geek5,如果不存在,则对geek6遵循相同的步骤,直到找到一个字符串在Trie中不存在。
// C++ program to assign usernames to users
#include
using namespace std;
#define MAX_CHAR 26
struct additional {
// is checks if the current node is
// leaf node or not
bool is;
// add counts number of concatenations
// of string are present in Trie
int add;
};
// represents Trie node
struct Trie {
// MAX_CHAR character children
Trie* character[MAX_CHAR];
// 10 numbers (from 0 to 9)
Trie* number[10];
// one additional struct children
additional a;
};
// function to get new node
Trie* getnew()
{
// initialising the Trie node
Trie* node = new Trie;
node->a.is = false;
node->a.add = -1;
for (int i = 0; i < MAX_CHAR; i++)
node->character[i] = NULL;
for (int i = 0; i < 10; i++)
node->number[i] = NULL;
return node;
}
// inserting a string into Trie
void insert(Trie*& head, string s)
{
Trie* curr = head;
for (int i = 0; i < s.length(); i++) {
if (s[i] - 'a' < 0) {
if (curr->number[s[i] - '0'] == NULL) {
curr->number[s[i] - '0'] = getnew();
}
curr = curr->number[s[i] - '0'];
}
else {
if (curr->character[s[i] - 'a'] == NULL)
curr->character[s[i] - 'a'] = getnew();
curr = curr->character[s[i] - 'a'];
}
}
curr->a.is = true;
}
// returns the structure additional
additional search(Trie* head, string s)
{
additional x;
x.is = false;
x.add = -1;
// if head is null directly return additional x
if (head == NULL)
return x;
Trie* curr = head;
// checking if string is present or not and
// accordingly returning x
for (int i = 0; i < s.size(); i++) {
if (s[i] - 'a' < 0) {
curr = curr->number[s[i] - '0'];
}
else
curr = curr->character[s[i] - 'a'];
if (curr == NULL)
return x;
}
x.is = curr->a.is;
x.add = curr->a.add;
return x;
}
// special function to update add variable to z
void update(Trie* head, string s, int z)
{
Trie* curr = head;
for (int i = 0; i < s.size(); i++) {
if (s[i] - 'a' < 0)
curr = curr->number[s[i] - '0'];
else
curr = curr->character[s[i] - 'a'];
}
curr->a.add = z;
}
void printUsernames(string username[], int n)
{
// Initialing a Trie root
Trie* head = getnew();
// Assigning usernames one by one
for (int i = 0; i < n; i++) {
string s = username[i];
additional x = search(head, s);
// if string is not present directly return it
if (x.is == false) {
cout << s << endl;
insert(head, s);
}
// to_string(x) converts integer x into string
else if (x.is == true) {
// start from x.add+1
int y = x.add + 1;
string x = s;
// continuing searching the string
// until a free username is found
while (1 < 2) {
// if free username is found
if (search(head, x + to_string(y)).is == false) {
// print it inser it and update add
cout << x << y << endl;
insert(head, x + to_string(y));
update(head, s, y);
break;
}
// else increment y
else if (search(head, x + to_string(y)).is == true)
y++;
}
}
}
}
// driver function
int main()
{
string name[] = { "geek", "geek0", "geek1", "geek" };
int n = sizeof(name) / sizeof(name[0]);
printUsernames(name, n);
return 0;
}
geek
geek0
geek1
geek2