Как эффективно создать «бесконечную» строку?

Всем привет.
Суть задачи в том, что дана строка str, индекс начала которой надо найти в другой строке numbers.
Строка numbers имеет вид: "12345678910", то бишь числа по возрастанию.
Допустим, str = "123", значит вывести надо 0.
Но если str равен, например, "15", то мы все равно должны найти правильный индекс (то есть, как я понимаю, превратить numbers в "123456789101112131415..."
Саму задачу я выполнить могу, но работает она слишком медленно. Уже второй день пытаюсь оптимизировать, но лучшее, что получилось, ниже.
Кто может подсказать что-либо? Программирую не так давно, поэтому мог написать полную чушь.
Примеры входных и выходных значений:
str = "456", выходные данные = 3.
str = "454", выходные данные = 79;
str = "99100", выходные данные = 187;
str = "123456798", выходные данные = 1000000071 (вот здесь я даже не могу получить результат, потому что очень долго выполняется).

static long findPosition(string str) {
    StringBuilder numbers = new StringBuilder("12345678910");
    BigInteger i = 10;
    StringBuilder temp = new StringBuilder(1000);

    // FindSubstring - алгоритм Кнутта-Морриса-Пратта для поиска индекса
    while (FindSubstring(str, numbers.ToString()) == -1) {
        // Здесь я часто менял "j < 100" на что-то другое, для разных значений скорость изменяется
        for (int j = 0; j < 100; j++) {
            // Здесь так же я менял на добавление большего количеств чисел, скорость тоже значительно увеличивалась, но 
            // но все равно программа работает медленно
            temp.AppendFormat("{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}", i + 1, i + 2, i + 3, i + 4, i + 5, i + 6, i + 7, i + 8, i + 9, i + 10);
            i += 10;
        }
        numbers.Append(temp);
        temp.Clear();
    }

    return FindSubstring(str, numbers.ToString());
}


  • Вопрос задан
  • 448 просмотров
Пригласить эксперта
Ответы на вопрос 3
longclaps
@longclaps
Суть задачи в том, чтобы вычислить индекс, не создавая строку numbers. Быстро и не пожирая память.
Ответ написан
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
1. Вначале - нужно составить формулу повышения разрядности позиций в зависимости от входа.
2. Затем - спозиционировать рекурсивно начиная со старшего разряда - вглубь.
3. Все прыжки - просуммировать и получите позицию.
(это задачка на решение фрактальных уравнений)
Ответ написан
Конечно аналитически найти индекс это true path, но сделать "в лоб" тоже можно. Для str = "123456798" ответ получишь через 3 минуты :)

using System;
using System.Collections.Generic;
using System.Linq;

namespace FindString
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "123456798";
            string buf = string.Concat(Generator.All().Take(str.Length));

            ulong index = 0;
            foreach (var c in Generator.All().Skip(str.Length))
            {
                if (buf == str)
                {
                    break;
                }

                buf = buf.Substring(1) + c;
                ++index;
            }

            Console.WriteLine("index is {0}", index);
            Console.ReadKey();
        }
    }

    public class Generator
    {
        public static IEnumerable<char> All()
        {
            ulong v = 0;
            while(true)
            {
                ++v;
                foreach(var c in v.ToString().ToCharArray())
                {
                    yield return c;
                }
            }
        }
    }
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы