Форум программистов, компьютерный форум CyberForum.ru

Название файла по маске - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
Asker
114 / 102 / 11
Регистрация: 18.12.2010
Сообщений: 378
29.11.2013, 19:53     Название файла по маске #1
Добрый вечер!

Пытаюсь решить олимпиадную задачу:
Кликните здесь для просмотра всего текста
Миша готовится к ЕГЭ по информатике. Сейчас он изучает задачу A4, в которой описывается работа с масками файлов:

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

Символ «?» (вопросительный знак) означает ровно один произвольный символ.

Символ «*» (звёздочка) означает любую последовательность символов произвольной длины, в том числе «*» может задавать и пустую последовательность.

Поскольку открытого банка задач для ЕГЭ по информатике не существует, Мише приходится тренироваться самостоятельно. Напишите программу, которая для каждого имени файла определит, подходит ли оно под заданную маску, чтобы Миша мог сверить свои ответы. Гарантируется, что в маске файла присутствует не более одного символа «*».

Входные данные

В первой строке содержится маска файла. В следующих 5 строках содержатся имена файлов по одному в строке. Имена файлов состоят из маленьких латинских букв, цифр и символа «.» (точка), в маске также могут содержаться символы «?» и «*» (символ «*» — не более одного раза). Длина каждой строки не превосходит 20 символов.

Выходные данные

Для каждого имени файла выведите слово «YES» если оно удовлетворяет маске и «NO» иначе. Выводить слова следует большими латинскими буквами без кавычек, каждое в новой строке.


В этой задаче нужно написать свою функцию, которая проверяла бы соответсвие соответствие названия файла некоторой маске. Название файла и длина маски не превышает 20 символов, в маске могут быть символы латинского алфавита, точка ("."), знак вопроса ("?") - означает любой символ и звездочка ("*", означает любую, даже пустую последовательность символов)- она может быть только одна.

Например, маске ?or*.d?? соттветствует файл lord2.doc, но не соответствует orsk.dat.

Как я представляю, как решать эту задачу: пока символы соответствуют друг другу, пробегаем строку слева направо и справа налево с двух концов до звездочки (если есть таковая); если смиволы совпали до этого момента, то все отлично; если нет - то все плохо. Но у меня возникла проблема с реализацией (я пытался написать эту программу, но она косая и не работает; не знаю, как учесть случаи разных длин строк и т.п.)
Кликните здесь для просмотра всего текста
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <string.h>
 
using namespace std;
 
int main()
{
    string mask, s;
    cin >> mask;
    for (int ct = 0; ct < 5; ++ct)
    {
        bool ok = true, zv = false;
        cin >> s;
        int sm = 0, i = 0;
        for (i = 0; i < max(s.length(), mask.length()); i++)
        {
            if (i > min(s.length(), mask.length()))
            {
                ok = false;
                break;
            }
            if (mask[i] == '*') break;
            if (s[i] != mask[i] && mask[i] != '?')
            {
                ok = false;
                cout << "mask[" << i << "] != s[" << i <<"]" << endl;
                break;
            }
        }
        int j= 0, t;
        for (j = s.length() - 1; j >= 0 && mask[j] != '*'; j--)
        {
            t = j - s.length() + mask.length();
            if (t < 0) break;
            if (s[j] != mask[t] && mask[t] != '?')
            {
                ok = false;
                cout << "right  mask[" << t << "] != s[" << j <<"]" << endl;
                break;
            }
        }
 
        if (!ok)
            cout << "NO" <<endl;
        else
            cout << "YES" << endl;
    }
    return 0;
}

Помогите, пожалуйста, реализовать эту программу!
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ullaluna
 Аватар для Ullaluna
8 / 6 / 1
Регистрация: 11.11.2013
Сообщений: 75
29.11.2013, 23:38     Название файла по маске #2
Аскер, под конец дня мой моск взорвался от одного прочтения задачи.

Для поиска файла по маске существует малоизвестная функция fnmatch. Да, и в с++ она тоже есть, не только в php!

http://pubs.opengroup.org/onlinepubs...s/fnmatch.html - это ее описание без примера.

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

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

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
26
27
28
29
30
31
32
#include <iostream>
#include <dirent.h>
#include <fnmatch.h>
#include <typeinfo>
#include <vector>
using namespace std;
 
 
int main() {
  char pathtofile[] = "/dev/";
  char mask[] = "video*";
  vector <char *> devices;
  
  DIR *dir = opendir(pathtofile);
  if(dir) {
    struct dirent *videodev;
    while((videodev = readdir(dir)) != NULL){
      if (fnmatch(mask, videodev->d_name, 0) == 0) {
    devices.push_back(videodev->d_name);
      }
    }
  }
  else
  {
    cout << "Error opening directory\n"<< endl;
    return -1;
  }
  for (int i = 0; i < devices.size(); i++) {
    cout << devices[i] << endl;
  }
    return 0;
}
Добавлено через 11 минут
P.S. Кстати, не исключено, что это функция под *nix, и в вендах ее тупо нет. Но я не знаю, и проверить не на чем.

Добавлено через 6 минут
P.P.S. Да, блин, она с POSIX'а. Но я гляжу, наши зарубежные коллеги как-то мастрячат ее на винду, и даже что-то официальное есть. Ну, на худой конец копируешь исходник и смотришь, как это реализовано. Пишешь свое. Все лучше, чем в пиццотый раз массивы перебирать, зная, что это никто после тебя не станет использовать.
vxg
Модератор
 Аватар для vxg
2639 / 1650 / 156
Регистрация: 13.01.2012
Сообщений: 6,213
30.11.2013, 06:54     Название файла по маске #3
Цитата Сообщение от Ullaluna Посмотреть сообщение
Для поиска файла по маске существует малоизвестная функция fnmatch
к сожалению человеку нужно
Цитата Сообщение от Asker Посмотреть сообщение
написать свою функцию
accept
4837 / 3236 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
07.12.2013, 00:55     Название файла по маске #4
Цитата Сообщение от Asker Посмотреть сообщение
я пытался написать эту программу, но она косая и не работает
это задача на конечный распознаватель, для которого нужно определить, принадлежит ли ему цепочка
материал
пример
Yandex
Объявления
07.12.2013, 00:55     Название файла по маске
Ответ Создать тему
Опции темы

Текущее время: 13:38. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru