Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Подсчёт символов, Одинаковых 
V
    Опции темы
APro
Дата 26.12.2008, 22:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 328
Регистрация: 5.12.2006

Репутация: 1
Всего: 1



Посмотрел я немножко кодов, не совсем понял как реализовать это:

Есть фраза: «Шла Саша по шоссе», и как мне в ней посчитать количество одинаковых символов и вывести результат. Для этой фразы должен получиться такой результат:

Код

3,1,3,3,1,2,1 // (3-ш, 1-л, 3-а, 3-с, 1-п, 2-о, 1-е)


Думаю понятно?


--------------------
Никогда не спорь с дураком, другие могут не заметить между вами разницы.
Чем реже открываешь рот, тем меньше слышишь глупостей.
PM MAIL WWW ICQ   Вверх
skyboy
Дата 26.12.2008, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



1. приводишь все символы к одному регистру.("шла саша по шоссе")
2. сортируешь символы в строке("аааелоопсссшшш")
3. считаешь количество повторений каждого символа.(что такое "цикл" в курсе?)
PM MAIL   Вверх
Dima 2015
Дата 26.12.2008, 23:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 287
Регистрация: 16.3.2008
Где: SPb

Репутация: 2
Всего: 2



APro, ну на рнр проще всего это сделать используя ассоциативные массивы с ключами - символами. Создаем массив, в который будем записывать результат по частоте каждой буквы, а сами буквы будут в нем ключами, пущай он будет зваться $result, ну и заводим переменную - счетчик - $counter.

Теперь тупо перебираем строку по символу, взяли символ и смотрим есть ли в нашем массиве такой ключ (ф-ция array_key_exists), если ключ есть - делаем +1 к значению элемента массива с этим ключем, если нету - присваиваем ему единицу. Взять $n-ый символ из строки - substr($str, $n, $n+1) если не путаю...

В результате получим массив:

$result = array (
['ш'] => 3,
['л'] => 1,
...
);

Про регистр забыл, действительно если надо не учитывать регистр то сначала строку надо в нижний, ну или в верхний регистр всю загнать...

Это сообщение отредактировал(а) Dima 2015 - 26.12.2008, 23:51
PM MAIL ICQ   Вверх
theworldcreator
Дата 27.12.2008, 00:12 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 362
Регистрация: 25.8.2007
Где: Москва

Репутация: 10
Всего: 13



Цитата

APro, ну на рнр проще всего это сделать используя ассоциативные массивы с ключами - символами. Создаем массив, в который будем записывать результат по частоте каждой буквы, а сами буквы будут в нем ключами, пущай он будет зваться $result, ну и заводим переменную - счетчик - $counter.

Теперь тупо перебираем строку по символу, взяли символ и смотрим есть ли в нашем массиве такой ключ (ф-ция array_key_exists), если ключ есть - делаем +1 к значению элемента массива с этим ключем, если нету - присваиваем ему единицу. Взять $n-ый символ из строки - substr($str, $n, $n+1) если не путаю...

В результате получим массив:

$result = array (
['ш'] => 3,
['л'] => 1,
...
); 

Я перепишу более оптимально, ты не против?) Просто в целом идея хорошая, но советы по реализации не современны
Код

$str = "Шла Саша по шоссе и сосала сушку";
$str = mb_strtolower(iconv('utf-8', 'cp1251', $str), 'cp1251');
$res = Array();
$len = strlen($str);
for($i = 0; $i < $len; $i++)
    $res[$str[$i]]++;
var_dump($res);

Комментарии:
во первых с удивлением обнаружил что массивам нельзя назначать русские буквы в юникоде в качестве ключей. Решил работать в cp1251. Далее оказалось что strtolower() не работает с русскими символами даже в cp1251! Из этих двух проблем вытекает монструозность второй строки.
И еще я не совсем уверен насколько правильно считать не объявленные элементы массива равными нулю. Но я изначально объявил $res как пустой массив(чтобы избежать проблемы с регистр глобалс, да и вообще использование этой переменной в той же области видимости), а потом у меня отработало нормальноsmile
Код

array
  'ш' => int 4
  'л' => int 2
  'а' => int 5
  ' ' => int 6
  'с' => int 6
  'п' => int 1
  'о' => int 3
  'е' => int 1
  'и' => int 1
  'у' => int 2
  'к' => int 1

PM MAIL WWW ICQ   Вверх
Dima 2015
Дата 27.12.2008, 01:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 287
Регистрация: 16.3.2008
Где: SPb

Репутация: 2
Всего: 2



theworldcreator, не, абсолютно не против, я так накидал, что с ходу в голову пришло.

А по поводу кодировок, вот эти строчки спасут юникод:

mb_internal_encoding("UTF-8");
mb_regex_encoding("UTF-8");

Поставь их перед тем. как использовать mb_ - строковые и рег-эксп функции и все должно быть окей.

Еще хочу извиниться, выше бред написал, $n-ый символ строки конечно же mb_substr($str, $n, 1), (считаются они от нуля). На счет подхода $str[$n], вот с ним как раз проблемы в юникоде. Я так понимаю из-за того, что за $n выступает номер байта в строке, а каждый русский символ то по 2 байта... поэтому и сделать его ключем массива не получается, ну я так понял. Так или иначе у меня вот так работает:

Код

// Установка кодировки
header('Content-type: text/html; charset=utf-8');
//Кодировка для строковых функций
mb_internal_encoding("UTF-8");
mb_regex_encoding("UTF-8");

$str = 'Шла Саша по шоссе с сосала';


$str = mb_strtolower($str);
$n = 0;
while ($char = mb_substr($str, $n, 1)) {
    $arr[$char]++;
    $n++;
}


print_r($arr);


Array
(
    [ш] => 4
    [л] => 2
    [а] => 5
    [ ] => 6
    [с] => 6
    [п] => 1
    [о] => 3
    [е] => 1
    [и] => 1
    [у] => 2
    [к] => 1
)

Результаты совпали с theworldcreator, как физик заявляю - это редко бывает, радуемся : )))

Добавлено @ 01:24
П.С. Да, на счет array_key_exists было лишним, можно сразу к еще не определенному элементу массива ++ сделать и все окей, ну и славно...

Это сообщение отредактировал(а) Dima 2015 - 27.12.2008, 01:26
PM MAIL ICQ   Вверх
teroni
Дата 27.12.2008, 01:52 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 15.5.2007
Где: Днепропетровск

Репутация: 8
Всего: 22



Ну если не пользоваться циклами, а использовать только встроенные средства для работы со строками - то можно еще немного сократить smile
Код

$str = "Шла Саша по шоссе и сосала сушку";
print_r(array_count_values(str_split(strtolower($str))));

З.Ы. С кодировками не заморачивался, у меня strtolower нормально работает и с СР1251.

Цитата(Dima 2015 @  27.12.2008,  01:22 Найти цитируемый пост)
можно сразу к еще не определенному элементу массива ++ сделать и все окей, ну и славно...
Если нотайсов не боитесь smile

Это сообщение отредактировал(а) teroni - 27.12.2008, 01:56
PM MAIL   Вверх
Dima 2015
Дата 27.12.2008, 02:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 287
Регистрация: 16.3.2008
Где: SPb

Репутация: 2
Всего: 2



teroni, специально сунул в скрипт сейчас ini_set("display_errors", "on"), хотя тестил на сервере, а там у меня временно и в .htaccess прописано, чтоб ошибки выводились, никаких нотайсов не видать... 0_о

Добавлено @ 02:21
teroni, 
А вообще твой вариант наверняка самый правильный, как я понимаю, там где можно использовать встроенные ф-ции, там надо это делать... ну почти всегда...

Добавлено через 4 минуты и 21 секунду
Вспомнилось высказывание...

Начинающий программист использует до 100 ф-ций языка
Среднего уровня - порядка 500
Профессионал - за 1000

Цифры возможно чуть наврал, но идея имеет место быть...

Это сообщение отредактировал(а) Dima 2015 - 27.12.2008, 02:22
PM MAIL ICQ   Вверх
skyboy
Дата 27.12.2008, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



Цитата(theworldcreator @  26.12.2008,  23:12 Найти цитируемый пост)
Далее оказалось что strtolower() не работает с русскими символами даже в cp1251!

насколько я знаю(и по своему опыту тоже) - это вполне решается установкой setlocale
PM MAIL   Вверх
theworldcreator
Дата 27.12.2008, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 362
Регистрация: 25.8.2007
Где: Москва

Репутация: 10
Всего: 13



Цитата

А по поводу кодировок, вот эти строчки спасут юникод:

mb_internal_encoding("UTF-8");
mb_regex_encoding("UTF-8");

Нет, они просто скажут библиотеке mb_ какую кодировку использовать если она не указанна в функции в явном видеsmile Причем вторая строка избыточна, т.к.(из мануала):
Цитата

The encoding  parameter is the character encoding. If it is omitted, the internal character encoding value will be used.


Цитата

Еще хочу извиниться, выше бред написал, $n-ый символ строки конечно же mb_substr($str, $n, 1), (считаются они от нуля). На счет подхода $str[$n], вот с ним как раз проблемы в юникоде. Я так понимаю из-за того, что за $n выступает номер байта в строке, а каждый русский символ то по 2 байта... поэтому и сделать его ключем массива не получается, ну я так понял.

Вы оказались правы, $str[0] возвращает первый значащий байт первого символа. Соответсвенно чтобы получить нормальный символ, придется извращаться:
Код

$res[$str[$i].$str[$i+1]];$i+=2;

Разумеется это не дело, ваш вариант лучше, однако оказалось что массивом все равно что у них в ключе, просто читаться будет как нечто страшное, ибо это только один байт из двух необходимых.
Цитата

можно сразу к еще не определенному элементу массива ++ сделать и все окей, ну и славно...

Цитата

И еще я не совсем уверен насколько правильно считать не объявленные элементы массива равными нулю. Но я изначально объявил $res как пустой массив(чтобы избежать проблемы с регистр глобалс, да и вообще использование этой переменной в той же области видимости)

Вы забыли объявить его пустымsmile
Цитата

Код

$str = "Шла Саша по шоссе и сосала сушку";
print_r(array_count_values(str_split(strtolower($str))));


Круто, уважаю!
PM MAIL WWW ICQ   Вверх
APro
Дата 27.12.2008, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 328
Регистрация: 5.12.2006

Репутация: 1
Всего: 1



Всем спасибо! Код действительно работал, вот только как мне получить только цифры???


--------------------
Никогда не спорь с дураком, другие могут не заметить между вами разницы.
Чем реже открываешь рот, тем меньше слышишь глупостей.
PM MAIL WWW ICQ   Вверх
theworldcreator
Дата 27.12.2008, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 362
Регистрация: 25.8.2007
Где: Москва

Репутация: 10
Всего: 13



Включить мозг.. Все данные уже есть даже в примерах кода этой темы, а если воспользоваться поиском...
PM MAIL WWW ICQ   Вверх
APro
Дата 27.12.2008, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 328
Регистрация: 5.12.2006

Репутация: 1
Всего: 1



Я изучаю PHP, но в циклах и массивах мало пока что понимаю... Я не монимаю как счётчик вывести :(


--------------------
Никогда не спорь с дураком, другие могут не заметить между вами разницы.
Чем реже открываешь рот, тем меньше слышишь глупостей.
PM MAIL WWW ICQ   Вверх
theworldcreator
Дата 27.12.2008, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 362
Регистрация: 25.8.2007
Где: Москва

Репутация: 10
Всего: 13



PM MAIL WWW ICQ   Вверх
APro
Дата 27.12.2008, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 328
Регистрация: 5.12.2006

Репутация: 1
Всего: 1



А может кто ткнёт меня носом в нужную ссылку?


--------------------
Никогда не спорь с дураком, другие могут не заметить между вами разницы.
Чем реже открываешь рот, тем меньше слышишь глупостей.
PM MAIL WWW ICQ   Вверх
APro
Дата 27.12.2008, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 328
Регистрация: 5.12.2006

Репутация: 1
Всего: 1



Я правильно сделал?

Код

$str = "Шла Саша по шоссе";
$text = array_values(array_count_values(str_split(strtolower($str))));

for ($i=0; $i<=count($text); $i++) {
    echo $text[$i];
}



--------------------
Никогда не спорь с дураком, другие могут не заметить между вами разницы.
Чем реже открываешь рот, тем меньше слышишь глупостей.
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.4055 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.