powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Инкрементирование строки
25 сообщений из 105, страница 2 из 5
Инкрементирование строки
    #39376724
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВhVostt,
В акуматике еще в условии запрет на использование регэкспов.

Решение без регекспов выше привёл.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376726
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TМой еще проще: сложение столбиком проходил в школе? Это оно и есть, +1 столбиком. Подробный алгоритм в учебнике по математике за 2 класс :)

И ты запутался в задачке для 2-го класса... Эх ты :)
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376736
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pallarisну и a9999 не прожует.

Вариант Хвоста надежнее
Это зависит от ТЗ, к сожалению ТС этот момент не озвучил. Поэтому каждый может обрабатывать пограничные состояния по своему усмотрению.

Я считаю что a9999 должно вызвать исключение, т.к. это переполнение.
Все подобные кодировки, что мне попадались, всегда имели фиксированную ширину, поэтому добавление лишнего символа я считаю неправильным. Если правильно добавлять символ, то в моем коде просто заменить throw на вставку '1'.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376737
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Строки в .NET не изменяемые, ты не можешь работать со строкой, как с массивом, а ты работаешь. Наигрубейшая ошибка надо сказать.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
  unsafe static void M1()
        {
            string s = "hVostt";
            fixed(char* ch = s)
            {
                ch[0] = 'H';
            }
            Console.WriteLine(s);
        }
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376742
Colt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVosttDima TЗаинтриговал, договаривай, а то может ты просто сам запутался в моем примере, есть повод так думать

Строки в .NET не изменяемые, ты не можешь работать со строкой, как с массивом, а ты работаешь. Наигрубейшая ошибка надо сказать.

Даже если предположить, что строки стали работать как массивы, твой "алгоритм" вообще какую-то ерунду делает, не относящуюся к задаче ТС. Не решает задачу короче.

Я думаю на самом деле ты хотел изобразить что-то типа этого:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
        public static string StrInc2([NotNull] string s)
        {
            if (string.IsNullOrEmpty(s)) throw new ArgumentException("Wrong string.", nameof(s));
            var b = new char[s.Length];
            var i = s.Length;
            while (--i >= 0 && char.IsDigit(s[i]))
            {
                var d = s[i] + 1;
                if (d > '9')
                {
                    b[i] = '0';
                }
                else
                {
                    b[i] = (char)d;
                    break;
                }
            }
            while (--i >= 0) b[i] = s[i];
            return new string(b);
        }



Сорри, может туплю, но где увеличивается цифра вижу, а вот случай, когда увеличенная цифра становиться больше 9 вижу только превращение ее в 0, но переноса единицы в следующий разряд не вижу.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376745
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВ,

У нас живёт в офисе код, который надрессирован за такие вещи больно царапаться и больно кусаться
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376747
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ColtСорри, может туплю, но где увеличивается цифра вижу, а вот случай, когда увеличенная цифра становиться больше 9 вижу только превращение ее в 0, но переноса единицы в следующий разряд не вижу.

Перенос единицы по сути -- продолжение цикла. Если нет переноса, то break.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376748
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВ,

Хотя такие вещи возможны, например, при работе с алгоритмами шифрования и интеропом, но это исключение.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376763
Syrex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ColtСорри, может туплю, но где увеличивается цифра вижу, а вот случай, когда увеличенная цифра становиться больше 9 вижу только превращение ее в 0, но переноса единицы в следующий разряд не вижу.

А может должно быть так:
SCA009 -> SCA0010 ?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376765
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Самое крутое, что скорее всего ТС больше здесь не появится :)
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376770
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttЯ думаю на самом деле ты хотел изобразить что-то типа этого
Я типа этого и изобразил, только с исключением при переполнении.

Как я уже понял надо было не тупо копировать строчку с исключением из твоего кода, а оформить понятнее. С исключением там косяк небольшой, на строке без букв его не будет, например "999"

Чуть поправил выдачу исключений, можешь потестить, этот запускается
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
        public static string StrInc(string v) {
			char[] s = v.ToArray();
			int i = s.Length - 1;
			for(; i >= 0; i--) {
				if(s[i] >= '0' && s[i] < '9') {
					s[i]++;
					break;
				} else if(s[i] == '9') {
					s[i] = '0';
				} else {
					throw new OverflowException();
				}
			}
			if(i < 0) throw new OverflowException();
			return new string(s);
		}
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376787
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttСтроки в .NET не изменяемые, ты не можешь работать со строкой, как с массивом, а ты работаешь.
В С/С++ меняются, тут нет, напутал немного.
hVosttНаигрубейшая ошибка надо сказать.
ХЗ что тут такого страшного, оно не компилируется. При всем желании не накосячишь. Суть была понятна, а это ляп кому надо сам поправит.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376823
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЯ считаю что a9999 должно вызвать исключение,
поддерживаю
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376841
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЧуть поправил выдачу исключений, можешь потестить, этот запускается

У тебя префиксы не поддерживаются, а у ТС есть примеры с префиксами.
Для поддержки последний OverflowException надо убрать.

И всё же, чтобы у тебя код был понятней, надо разделить блок где ты работаешь с цифрами и где работаешь с другими символами.

Вот это:

if(s[i] >= '0' && s[i] < '9')
} else if(s[i] == '9') {

Это жесть! Надо внимательно вчитываться во все условия, чтобы 100% убедиться, что обрабатываются только цифры. В моём решении в цикл вход натурально возможен только если char.IsDecimal(s[i]) -- никаких двусмысленностей, 100% только числа внутри, это очевидно сразу при первом взгляде.

Я настоятельно не рекомендую писать код, который трудно читать. Иногда достаточно совсем небольших усилий, чтобы код стал понятным и прозрачным. Сложные вычурные условия вообще редко когда дают профит в производительности, скорее даже почти никогда не дают.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376878
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttУ тебя префиксы не поддерживаются, а у ТС есть примеры с префиксами.
Для поддержки последний OverflowException надо убрать.
Затести, я же написал что код запускается.
Код: c#
1.
2.
3.
4.
5.
			Console.WriteLine(StrInc("01"));
			Console.WriteLine(StrInc("09"));
			Console.WriteLine(StrInc("a01"));
			Console.WriteLine(StrInc("a09"));
			Console.WriteLine(StrInc("a99"));


Результат
Код: plaintext
1.
2.
3.
4.
5.
02
10
a02
a10

Необработанное исключение: System.OverflowException

hVosttНадо внимательно вчитываться во все условия, чтобы 100% убедиться, что обрабатываются только цифры. В моём решении в цикл вход натурально возможен только если char.IsDecimal(s[i]) -- никаких двусмысленностей, 100% только числа внутри, это очевидно сразу при первом взгляде.
Туда вообще смотреть не надо, надо просто описание к функции написать.
hVosttСложные вычурные условия вообще редко когда дают профит в производительности, скорее даже почти никогда не дают.
ХЗ что тяжелее: две элементарных проверки значения или вызов функции. Обычно второе.
Потом пройдись пошагово отладчиком по своему и моему коду и просто посчитай сколько действий у тебя и у меня.

Правда тут в первую очередь надо избавляться от перегонки из строки в массив и обратно, а потом уже прочий тюнинг.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376880
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сложение столбиком освоили?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376887
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПравда тут в первую очередь надо избавляться от перегонки из строки в массив и обратно
открой для себя StringBuilder
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39376905
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima TПравда тут в первую очередь надо избавляться от перегонки из строки в массив и обратно
открой для себя StringBuilder
Что он поменяет если на входе и выходе строка нужна?

У него тоже массив внутри.
StringBuilder.cs
Код: c#
1.
internal char[] m_ChunkChars;



ИМХУ Тут указатели открывать надо 20055906 .
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377002
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TХЗ что тяжелее: две элементарных проверки значения или вызов функции. Обычно второе.
Потом пройдись пошагово отладчиком по своему и моему коду и просто посчитай сколько действий у тебя и у меня.

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

Хотя может тебя просто прикалывают алгоритмические задачки и конечные автоматы, но в реале ты так не пишешь, а то я тут распинаюсь
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377011
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПравда тут в первую очередь надо избавляться от перегонки из строки в массив и обратно, а потом уже прочий тюнинг.

Зачем? А если буквально через некоторое время задача усложнится, и надо будет прибавлять не 1, а 10? Или в зависимости от префикса? Твой код придётся полностью переписывать, в коде с регекспами я просто сделаю крошечное изменение: 1 заменю на 10! А если надо будет вот такие строки обрабатывать:

AK0001R-P
AK0002R-P

И при достижении 9999 должна меняться буква? Опять закатывать рукава и писать новый автомат?
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377064
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttDima TХЗ что тяжелее: две элементарных проверки значения или вызов функции. Обычно второе.
Потом пройдись пошагово отладчиком по своему и моему коду и просто посчитай сколько действий у тебя и у меня.

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

Хотя может тебя просто прикалывают алгоритмические задачки и конечные автоматы, но в реале ты так не пишешь, а то я тут распинаюсь
Иногда пишу, но очень редко. Проекты разные бывают. Если простую функцию надо 100500 раз подряд вызвать, то есть смысл над ней поработать. Например парсинг файлов.

У меня случай нестандартный, другим мою писанину точно сопровождать не придется, поэтому если и потребуется пол-бутылки, то для меня же, если в этот код полезу пару лет спустя.

PS Кусочек заточенного реального кодаНаписал свою обертку для чтения DBF напрямую из файла.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
        Byte[] row; // Текущая запись
...
        // Получение значения поля в Int32 по названию
        public Int32 AsInt32(String field) {
            return AsInt32(GetFieldNum(field));
        }

        // Получение значения поля в Int32 по номеру
        public Int32 AsInt32(Int32 col_num) {
            var f = fields[col_num];
            Int32 end = f.offset + f.size;
            Int32 i = 0;
            Int32 pos = f.offset;
            while (pos < end && row[pos] == 32) pos++;
            while (pos < end) {
                Byte b = row[pos];
                if (b >= 48 && b <= 57) {
                    i = i * 10 + b - 48;
                } else {
                    break;
                }
                pos++;
            }
            return i;
        }


Как видишь тут еще жестче. Зато ни одного new.

эту строчку узнаешь?
Код: c#
1.
                if (b >= 48 && b <= 57) {


Тот самый Char.IsDigit(), именно так Byte проверяется быстрее даже чем
Код: c#
1.
                if (b >= '0' && b <= '9') {



Если был бы метод Int32.Parse(Byte[], Length, Оffset), то весь этот код можно было бы выкинуть.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377076
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
Код: c#
1.
if (b >= 48 && b <= 57) {


Dima TТот самый Char.IsDigit(), именно так Byte проверяется быстрее даже чем

IsDigit работает очень и очень быстро, зря ты так

К слову, строка содержит символы, а не байты. Некоторый юникод, попавший в твою функцию может порвать её в клочья, а IsDigit легко выдержит удар.

Разницы по скорости между

b >= 48 && b <= 57

и

c >= '0' && c <= '9'

Нет. Только во втором варианте хотя бы понятно, что имеется в виду. В первом увы, какие-то магические числа.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377097
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttК слову, строка содержит символы, а не байты. Некоторый юникод, попавший в твою функцию может порвать её в клочья, а IsDigit легко выдержит удар.

В DBF юникода не бывает, там ASCII кодировки. Тип numeric хранится как число записанное строкой.

Как понимаю при сравнении byte и char сначала идет неявное приведение типов к общему знаменателю, а при указании числом нет. Может еще что-то влияет. Когда писал изначально было if(b >= '0' && b < '9'), при тестах на скорость попробовал поменять на числа, стало быстрее. Было бы это мелочью, я бы не заметил из-за погрешности измерений, тестил разбором большого файла.
Char.IsDigit() не догадался затестить, но думаю что все-таки медленнее, т.к. "IsDigit легко выдержит удар" не может быть за бесплатно.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377137
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКак понимаю при сравнении byte и char сначала идет неявное приведение типов к общему знаменателю, а при указании числом нет.

Занимательно, что ты даже не хочешь глянуть в IL код, чтобы убедиться, что это не так :)

Абсолютно параллельно с чем ты там сравниваешь byte или char, потому что они кладутся на стек как Int32 значения.

b <= '9'
b <= 57

Генерируют абсолютно идентичный код. Один в один. Вот из-за кучи мелких заблуждений, из-за недоверия к компилятору, который отлично умеет оптимизировать код, вырастают твои никому не нужные костыли.
...
Рейтинг: 0 / 0
Инкрементирование строки
    #39377144
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T"IsDigit легко выдержит удар" не может быть за бесплатно.

Ты на чтении DBF теряешь времени больше, чем может отработать миллион вызовов IsDigit. Гораздо логичнее выглядит выражение "пустыню пылесосить", чем замена IsDigit на сравнения с числами. Но это уже у кого какие тараканы в голове
...
Рейтинг: 0 / 0
25 сообщений из 105, страница 2 из 5
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Инкрементирование строки
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]