Самый быстрый способ обратить вспять в строке в C # .net

* означает ноль или более предыдущего выражения.

Другими словами, выражение необязательно.

Вы можете определить целое число, подобное этому:

-*[0-9]+

Другими словами, необязательный отрицательный знак, за которым следует одна или несколько цифр.

13
задан Cœur 27 October 2018 в 09:28
поделиться

10 ответов

Я думаю, что это могло бы быть быстрее, чтобы сделать оперативное сравнение. При инвертировании строки Вы имеете к:

  1. Инстанцируют нового строкового объекта (или объекта StringBuffer)
  2. Копия, данные (наоборот) от первой строки до новой строки
  3. Делают Ваше сравнение.

при выполнении сравнения на месте Вы делаете только последний шаг. Даже затем, Ваше сравнение является только половиной строки (или половиной - 0.5, в случае нечетного числа символов). Что-то как следующее должно работать:

static bool IsPalindromic(string s){
    int len = s.Length;
    int half = len-- >> 1;
    for(int i = 0; i < half; i++)
        if(s[i] != s[len - i])
            return false;
    return true;
}

РЕДАКТИРОВАНИЕ:

, Хотя это отвечает на вопрос OP, решения, предлагаемые ggf31416 и , конфигуратор решает реальную потребность OP приблизительно на 30% быстрее моими тестами. решением конфигуратора является крошечный бит быстрее, чем ggf31416, если Вы преобразовываете его в статический метод и используете int с вместо ulong с (но намного медленнее, иначе).

<час>

Кстати, пробежка этих примеров для решения проблемы упоминания OP (находящий самый большой палиндромический продукт любых двух трехзначных чисел) с простым (возможно, naГЇve) цикл ниже:

for(int i = 100; i < 1000; i++)
    for(int j = i; j < 1000; j++) // calculations where j < i would be redundant
        ...

урожаи следующие результаты на моей машине:

IsPalindromic(product.ToString()) took 0.3064174 seconds.
ggf31416Reverse(product) == product took 0.1933994 seconds.
configuratorReverse(product) == product took 0.1872061 seconds.

Каждый приводит к корректному результату 913 * 993 = 906609.

13
ответ дан Community 27 October 2018 в 19:28
поделиться
  • 1
    Обратите внимание на это, если Вы source сценарий, basename [111] возвратит родительский сценарий. – scribu 20 September 2012 в 11:59

Вы хотят сравнить число с его реверсом, это может быть быстрее для инвертирования подразделения использования числа вместо того, чтобы преобразовать его в строку. Я все еще должен протестировать скорость его.

 private static int Reverse(int num) {
     int res = 0;
     while (num > 0) {
        int rm ;
        num = Math.DivRem(num, 10, out rm);
        res = res * 10 + rm;
     }
     return res;
  }

РЕДАКТИРОВАНИЕ: DivRem был приблизительно на 1% быстрее, чем подразделение и модуль в моем компьютере. Оптимизация скорости является выходом, если последняя цифра 0:

  private static int Reverse(int num) {
     int res = 0;
     int rm;
     num = Math.DivRem(num, 10, out rm);
     //Some magic value or return false, see below.
     if (rm == 0) return -1 ; 
     res = res * 10 + rm;
     while (num > 0) {
        num = Math.DivRem(num, 10, out rm);
        res = res * 10 + rm;
     }
     return res ;
  }

Создание метода возвратить bool было немного медленнее, чем по сравнению с bool в цикле в моем компьютере, но я не понимаю почему. Протестируйте в своем компьютере.

Умножение и бит-shifing должны быть быстрее, чем подразделение, но вероятно не достаточно точны.Править: использование долго кажется быть достаточно точным.

  private static int FastReverse(int num) {
     int res = 0;
     int q = (int)((214748365L * num) >> 31);
     int rm = num - 10 * q;
     num = q;
     if (rm == 0) return -1;
     res = res * 10 + rm;
     while (num > 0) {
        q = (int)((214748365L * num) >> 31);
        rm = num - 10 * q;
        num = q;
        res = res * 10 + rm;
     }
     return res;
  }

(214748365L * цифра)>> 31 равно мне / 10 до 1,073,741,829, где 1 / 10 дает 107374182 и умножение +, двоичное смещение дает 107374183.

15
ответ дан ggf31416 27 October 2018 в 19:28
поделиться

Не был бы, инвертируя число быть быстрее?

// unchecked code, don't kill me if it doesn't even compile.
ulong Reverse(ulong number) {
    ulong result = 0;

    while (number > 0) {
        ulong digit = number % 10;
        result = result * 10 + digit;
        number /= 10;
    }

    return result;
}
21
ответ дан configurator 27 October 2018 в 19:28
поделиться
  • 1
    И также это не работает хорошо в сценариях загруженная оболочка входа в систему (~/.bashrc,/etc/profile.d /*). " BASH_SOURCE" и " BASH_LINENO" намного лучше, хотя they' ре bashisms. – pevik 29 April 2014 в 18:33
  • 1
    Я также предпочитаю использовать переменные BASH_*, как Вы описали их. Here' s хорошая статья о том, как отладить сценарии удара, на которые я сослался в прошлом: aymanh.com/how-debug-bash-scripts – Yzmir Ramirez 5 September 2011 в 12:50
string test = "ABC";
string reversed = new String(test.ToCharArray().Reverse().ToArray());
3
ответ дан 27 October 2018 в 19:28
поделиться

Используя функцию FastReverse ggf31416, вот решение проблемы Euler's Проекта № 4, который завершается на моем компьютере в 47 мс.

using System;
using System.Diagnostics;

namespace Euler_Problem_4
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch s = new Stopwatch();
            s.Start();

            int t = 0;

            for (int i = 999; i > 99; i--)
            {
                for (int j = i; j > 99; j--)
                {
                    if (i*j == FastReverse(i*j))
                    {
                        if (i * j > t)
                        {
                            t = i * j;
                        }
                    }
                }
            }

            Console.WriteLine(t);

            s.Stop();
            Console.WriteLine("{0}mins {1}secs {2}ms", s.Elapsed.Minutes, s.Elapsed.Seconds, s.Elapsed.Milliseconds);
            Console.ReadKey(true);

        }

        private static int FastReverse(int num)
        {
            int res = 0;
            int q = (int)((214748365L * num) >> 31);
            int rm = num - 10 * q;
            num = q;
            if (rm == 0) return -1;
            res = res * 10 + rm;
            while (num > 0)
            {
                q = (int)((214748365L * num) >> 31);
                rm = num - 10 * q;
                num = q;
                res = res * 10 + rm;
            }
            return res;
        }
    }
}
0
ответ дан GateKiller 27 October 2018 в 19:28
поделиться
  • 1
    Существует Знаток repos здесь, по-видимому: jogamp.org/deployment/maven . Но попытка использовать их с Простым Инструментом Сборки сообщает, что нет никакого ivy.xml... – axel22 4 July 2012 в 05:39
public static String Reverse(string input) {
  var length = input.Length;
  var buffer = new char[length];
  for ( var i= 0; i < input.Length; i++ ) {
    buffer[i] = input[(length-i)-1];
  }
  return new String(buffer);
}

РЕДАКТИРОВАНИЕ: Doh! Забыл делить на два длину для перфекта :)

1
ответ дан JaredPar 27 October 2018 в 19:28
поделиться
0
ответ дан Mladen Prajdic 27 October 2018 в 19:28
поделиться
  • 1
    В значительной степени все другие ответы здесь заменяются этим, за исключением битов о контакте с собственными библиотеками. – metasim 30 November 2012 в 07:08
string Reverse(string s)
{
  return new string(s.ToCharArray().Reverse().ToArray());
}
0
ответ дан Jesper Palm 27 October 2018 в 19:28
поделиться
  • 1
    Я don' t как пользовательский подход загрузчика, и я с тех пор переключился на Муравья и I' m теперь довольно довольный им. Однако Ваш ответ является безусловно самым подробным и информативным для этой проблемы, таким образом, I' ll отмечают его, как принято. – Ricket 14 January 2010 в 01:29

Класс секундомера необходимо сбрасывать после каждого запуска. приведенный ниже код был исправлен

var d = s.ToCharArray();
Array.Reverse(d);
return s == new string(d);

using System;
using System.Diagnostics;

namespace longeststring_codegolf
{
    class Program
    {
        static void Main(string[] args)
        {
            int t = 0, v = 0;
            var sw = new Stopwatch();

            sw.Start();
            for (int i = 999; i > 99; i--)
                for (int j = 999; j > 99; j--)
                    if ((v = i * j) > t && IsPalindromicMine(v.ToString()))
                        t = v;
            sw.Stop();

            var elapsed = sw.Elapsed;
            var elapsedMilliseconds = sw.ElapsedMilliseconds;
            var elapsedTicks = sw.ElapsedTicks; 
            Console.WriteLine("Ticks: " + elapsedTicks.ToString());//~189000
            Console.WriteLine("Milliseconds: " + elapsedMilliseconds.ToString()); //~9

            sw = Stopwatch.StartNew();
            for (int i = 999; i > 99; i--)
                for (int j = 999; j > 99; j--)
                    if ((v = i * j) > t && IsPalindromic(v.ToString()))
                        t = v;
            sw.Stop();
            var elapsed2 = sw.Elapsed;
            var elapsedMilliseconds2 = sw.ElapsedMilliseconds;
            var elapsedTicks2 = sw.ElapsedTicks; 
            Console.WriteLine("Ticks: " + elapsedTicks2.ToString());//~388000
            Console.WriteLine("Milliseconds: " + elapsedMilliseconds2.ToString());//~20

        }

        static bool IsPalindromicMine(string s)
        {
            var d = s.ToCharArray();
            Array.Reverse(d);
            return s == new string(d);
        }

        static bool IsPalindromic(string s)
        {
            int len = s.Length;
            int half = len-- >> 1;
            for (int i = 0; i < half; i++)
                if (s[i] != s[len - i])
                    return false;
            return true;
        }

    }
}
-1
ответ дан 1 December 2019 в 17:26
поделиться
Другие вопросы по тегам:

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