Форум: "Начинающим";
Текущий архив: 2007.01.28;
Скачать: [xml.tar.bz2];
ВнизРазбор строки. Найти похожие ветки
← →
.1. (2007-01-13 18:14) [0]Есть такая задача -- имеется некая стринговая переменная, в которой содержится некоторая строка, допустим "wewewew", необходимо определить сколько раз в этой строке встречаеются уникальные символы, ну т.е. в нашем случае -- это 2: "w", "e". написал функцию, которая проверяет содержиться ли указанное кол-во в указанной строке и возвращает булевый результат. Но просто хотелось бы узнать, возможно ли упростить и улучшить мою функцию?
(*
Value -- это входящий параметр проверяемой строки
RefLen -- максимальное кол-во уникальных символов вход. в строку
*)
function IsRefString(Value: shortstring; const RefLen: Byte): Boolean;
var
Tmp: string;
Cnt: Byte;
begin
for Cnt := 1 to Length(Value) do
if Pos(Value[Cnt], Tmp) <= 0 then tmp := tmp + Value[Cnt];
Result := Length(Tmp) = RefLen;
end;
← →
Kolan © (2007-01-13 18:52) [1]"сколько раз "
А у тебя Boolean
← →
.1. (2007-01-13 18:57) [2]Я там написал, какую сделал функцию. Это, я просто для отладки функцию делал, что бы проверить корректность работы, в любом случае смысл написанного в функции не теряется.
← →
Джо © (2007-01-13 18:59) [3]Тогда ответ на вопрос «хотелось бы узнать, возможно ли упростить и улучшить мою функцию» таков: «эту функцию нужно переделать», ибо она не решает поставленной задачи :)
← →
default © (2007-01-13 19:01) [4]хз, смотря что тебе надо
можешь иметь массив Fs: Array[ #0..#255] of Boolean
изначально всё элементы ставишь в False
и потом проверки типа if not Fs[Value[Cnt]] then ...встретился символ ранее не встртившийся ... Fs[Value[Cnt]] = True....делаешь что необходимо тут
← →
Kolan © (2007-01-13 19:02) [5]Предлогаю засести списочек(TList) экземпляров подобного класса:
TParam = class
FName: Char
FCount: Integer;
end;
Свойства и обл. видимости на тебе.
В цикле идешь по строке и соотв в списочке инкрементируешь нужный параметр. Оч. просто имхо...
← →
.1. (2007-01-13 19:04) [6]Переделал :)
(*
Value -- это входящий параметр проверяемой строки
RefLen -- максимальное кол-во уникальных символов вход. в строку
*)
function IsRefString(Value: shortstring): Byte;
var
Tmp: shortstring;
Cnt: Byte;
begin
for Cnt := 1 to Length(Value) do
if Pos(Value[Cnt], Tmp) <= 0 then tmp := tmp + Value[Cnt];
Result := Length(Tmp);
end;
← →
default © (2007-01-13 19:06) [7]а чё ты со строкой ShortString работаешь? странно как-то
← →
Kolan © (2007-01-13 19:07) [8]«Value — — это входящий параметр проверяемой строки»
А это что значит?
ЗЫ
Как я посоветовал в [5] за один проход сразу все получишь значения. Имхо быстрее чем га каждое вызывать ф-цию.
← →
.1. (2007-01-13 22:20) [9]ShortString -- а что плохого в этом?, просто мне больше и не нужно...
«Value — — это входящий параметр проверяемой строки»
А это что значит?
На этот комментарий можно не обращать внимание :).
Как я посоветовал в [5] за один проход сразу все получишь значения. Имхо быстрее чем га каждое вызывать ф-цию.
Я честно говоря прочитал несколько раз, но не понял, совсем не понял. Может, если есть возможность подкрепишь более длинным разъяснением?
← →
ors_archangel © (2007-01-13 22:52) [10]Следуя предложению default [4], можно написать такое:
function CountUniqueChars(const s: string): integer;
var
c: array[char] of boolean;
i: integer;
j: char;
begin
FillChar(c[ #0],sizeof(c),false);
for i := 1 to length(s) do c[s[i]] := true;
result := 0;
for j := low(c) to high(c) do inc(result, ord(c[j]));
end;
Комментарии:
• CountUniqueChars переводится как "Подсчитай уникальные символы", примерно так :)
• параметр - целевая строка передаётся как const - это ускоряет работу с ним, вместо ShortString использован string - он то же чаще всего более эффективен
• Массив c - имеет размер 256 байт, т.е. по байту-флажку на символ, ведь ANSi кодировка, которую использует тип string (хотя так говорить не правильно, тип всего лишь хранит данные и не связан с их конечной интерпретацией) тратит 8 бит на символ, т.е. 1 байт на символ, тип элементов - boolean - это логический тип (назван в честь Буля, был такой учёный), его множество значений составляют всего два значение: ture - истина (в Delphi кодируется 1) и false - ложь (в Delphi) кодируется 0, в принципе для этого типа достаточно log2 2 = 1 бит, но 8 бит - это минимальная (но не элементарная) единица информации при обмене с оперативной памятью, поэтому на самом деле здесь тратится в 8 раз больше памяти, чем нужно, но зато, мы получаем отличную скорость!
• FillChar - заполняет произвольную область памяти определённым значением, в данном коде эта функция "обнуляет" массив c, т.о. мы отмечаем, что никакие символы не используются, потому что массив c хранит именно факт использования каждого символа, т.е. если c["ф"] = true - значит символ "ф" используется, но вначале ничего ещё нет, поэтому все c[x] должны быть false, поэтому третий параметр у FillChar как раз false, если интересно, что это за sizeof(c) во втором параметре, то сообщаю, что так мы даём знать функции FillCHar размер нашего массива, сама она его узнать не может, потому что оперирует не с массивами, а с областями в памяти, которые могут быть чем угодно
• Далее в цикле получаем информацию о том, какие символы используются и запоминаем её в массиве c, например, если s = "wewe", то s[1] = "w", соответсвенно на первой итерации (шаге) цикла (когда i=1), мы запомним в c[s[1]] т.е. в c["w"] значение true, другими словами, отметим, что символ "w" используется
• result := 0 - пока всё ещё считаем, что нет символов, дальше в цикле опровергаем это увеличивая значение result каждый раз, когда c[j] установленно, т.е. например, когда j будет равно "w", с[j] будет равно c["w"], что равно true, а ord(true)=1 (код значения true), поэтому result увеличится (ведь inc - это операция инкремента, от. англ. increment - увеличение, эта операция увеличивает значение переменной на 1, если не имеет параметров, но в нашем случае мы явно передаём, на сколько нужно изменить значение). Если какое-то c[j] = false, то result не будет увеличиваться, т.к. ord(false) = 0, а inc(result,0) - не меняет result
← →
default © (2007-01-13 22:53) [11]
function IsRefString(Value: shortstring): Byte;
var
IsExist: Array[ #0..#255] of Boolean;
i: Integer;
begin
// заполняшь тут IsExist нулями(False), не помню какая там процедура,
// Delphi не установлена - не могу посмотреть
Result := 0;
for i := 1 to Length(Value) do
if not IsExist[Value[i]] then begin
IsExist[Value[i]] = True;
Inc(Result)
end;
end;
← →
ors_archangel © (2007-01-13 22:55) [12]To Kolan
Имхо, не стоит создавать класс для такой простой задачи, т.к. он не только менее экономичен по памяти, но и замедлит работу в данном случае (Одно динамическое создание n классов чего будет стоить)
← →
ors_archangel © (2007-01-13 22:57) [13]
> // заполняшь тут IsExist нулями(False), не помню какая
> там процедура,
Хотя бы цикл написал бы:
for c := #0 to #255 do IsExists[c] := false;
:)))
← →
default © (2007-01-13 22:58) [14]ors_archangel © (13.01.07 22:57) [13]
цикл медленно
FillChar кусками заполняет память
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.01.28;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.047 c