*
означает ноль или более предыдущего выражения.
Другими словами, выражение необязательно.
Вы можете определить целое число, подобное этому:
-*[0-9]+
Другими словами, необязательный отрицательный знак, за которым следует одна или несколько цифр.
Я думаю, что это могло бы быть быстрее, чтобы сделать оперативное сравнение. При инвертировании строки Вы имеете к:
при выполнении сравнения на месте Вы делаете только последний шаг. Даже затем, Ваше сравнение является только половиной строки (или половиной - 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
.
Вы хотят сравнить число с его реверсом, это может быть быстрее для инвертирования подразделения использования числа вместо того, чтобы преобразовать его в строку. Я все еще должен протестировать скорость его.
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.
Не был бы, инвертируя число быть быстрее?
// 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;
}
string test = "ABC";
string reversed = new String(test.ToCharArray().Reverse().ToArray());
Используя функцию 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;
}
}
}
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! Забыл делить на два длину для перфекта :)
попробуйте это также: http://weblogs.sqlteam.com/mladenp/archive/2006/03/19/9350.aspx
string Reverse(string s)
{
return new string(s.ToCharArray().Reverse().ToArray());
}
Класс секундомера необходимо сбрасывать после каждого запуска. приведенный ниже код был исправлен
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;
}
}
}
source
сценарий,basename [111]
возвратит родительский сценарий. – scribu 20 September 2012 в 11:59