Лучшее, что я могу придумать, - это только частичное генерирование строки.Учитывая подстроку и количество повторений, вы, конечно, можете просто использовать modulo
и определить, где вы попадете в подстроку.Проблема здесь в том, что вы повторяете всю подстроку до того момента, когда вы видите число, включая любые предыдущие дубликаты подстрок.
В принципе, я не могу придумать математического способа сделать это, я думаю, вам всегда нужно будет генерировать строку до итерации до той, которая вызовет s.length() > k
, или до последней цифрыво входной строке, в зависимости от того, что наступит раньше.Затем вы можете k%s.length()
найти правильный символ.
В C ++ это выглядит так:
char getK(string s, int k){
string genString = "";
string tempString = "";
string digits = "0123456789";
char c = '\0';
const char * cc = &c;
for (int i = 0; i < s.length(); i++){
c = s[i];
if (digits.find(c) != std::string::npos ){ // Digit
if (i == s.length()-1 || k < genString.length()*atoi(cc)){ // Final digit or the next substring will contain genString[k]
return genString[k%genString.length()]; // Modulo to find character location
}
tempString = genString;
genString = "";
for (int i = 0; i < atoi(cc); i++){
genString += tempString;
}
} else { // Not a digit
genString += c;
}
if (genString.length() > k) return genString[k]; // genString contains genString[k]
}
return genString[k]; // Silence compiler warnings
}
И может использоваться следующим образом:
int main()
{
string s = "a2b3c7g3g8r4w5rf5";
for (int k = 0; k < 20; k++){
cout << i << ": " << getK(s, k) << endl;
}
}
Если вы поместите в цикл некоторые операторы cout
, вы увидите, что он генерирует только столько строки, сколько ему необходимо.