Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Нужна помощь с 3 лабами (за деньги)

15K
10 декабря 2009 года
Ybr
31 / / 19.03.2007
Здравствуйте!
Ниже будут условия для трех моих лабораторных по программированию (на C++, в Visual Studio 2008 [ну, сдавать на нем]). Хочется узнать, за сколько сделаете и в какие сроки.
Проги нужно писать без особых умностей и не скупиться на комментарии. Я должен понять код, иначе будут проблемы с последующей сдачей.
В C++ разбираюсь плохо, но и не ноль полный: из 10 почти 6.5 лаб сделал сам:)

На всякий случай задания даю в виде прикрепленного файла Word. И большая просьба: не цитировать в форуме задание: мой препод хорошо умеет пользоваться гуглом:)

PS
"Лабы" - это все условия лаб в текстовом файле;
297
11 декабря 2009 года
koodeer
1.2K / / 02.05.2009
Цитата: Ybr
...
на C++, в Visual Studio 2008
...
"Lab7" - это я попытался сделать Лабу 7, №1. Все сделал, осталось только придумать, как загружать исходную строку.



Седьмая лаба действительно практически сделана.

Замечания: System и System::IO - это пространства имён FCL платформы .NET. То есть предназначены для "управляемого" C++. Короче, выкидываем эти строки:

 
Код:
using namespace System; // удаляем
using namespace System::IO; // удаляем

Раз уж вы пишете на C++, а не на C, то для чтения из файла лучше использовать не FILE *f (что подразумевает применение fscanf), а потоки:
 
Код:
#include <fstream>

//FILE *f;//хранится заданная фраза - это выкидываем

ifstream f;         // объявляем поток для чтений
f.open("test.txt"); // открываем поток
getline(f, s);      // читаем строку
f.close();          // закрываем поток

Если теперь запустить программу, выскочит ошибка. Причина - не задано начальное значение переменной k. Исправляется это просто: unsigned int i = 0, j, k = 0; // счетчик. Мораль: переменные нужно инициализировать всегда!
15K
11 декабря 2009 года
Ybr
31 / / 19.03.2007
Спасибо огромное! И правда, все заработало. На самом деле у меня проблема в С++ только одна, но большая: язык сложный, объемный. Каждую задачу можно решить несколькими способами. Какой из них самый простой я, естественно, не знаю.
Поэтому в процессе поиска нечаянно натыкаюсь на решение моей проблемы, разбираюсь много-много часов подряд, а потом оказывается, что тоже самое можно сделать существенно проще (например - я пытался использовать класс String^, но потом оказалось, что гораздо проще работать со string. Разницу так и не просек).

koodeer, у меня сейчас появилась отличная идея. Я буду вам очень благодарен, если поддержите меня.
Вот вы прочитали тексты трех лаб, и, конечно, видите решение. А не могли бы по каждой кратко написать, в каком направлении мне искать информацию?
Идея в том, чтобы я не копал весь инет в поисках сам-не-знаю-чего, а искать прицельно то, что поможет решить задачу.

PS Ошибок на тему инициализации k не возникло. Даже Предупреждений не было :)
297
11 декабря 2009 года
koodeer
1.2K / / 02.05.2009
Цитата: Ybr
PS Ошибок на тему инициализации k не возникло. Даже Предупреждений не было


Ошибок не было? Будут! Очевидно вы компилили программу в конфигурации Release. Если скомпилировать в конфигурации Debug, то ошибка возникает всегда:


Разница есть. Если в объявлении переменных (типов) присутствует знак ^ - значит, это один из типов управляемого C++.NET. Если в своих исканиях по интернету встречаете код C++ с такими знаками, то можете сразу его пропускать. Аналогично, если в примерах кода встречаются записи using namespace System; это тоже свидетельство управляемого C++. Также не обращайте внимание на код C++, если прямо написано, что он под платформу .NET. Вам это пока не нужно. В принципе, можно смешивать в одной программе управляемый и неуправляемый код, но лучше этого не делать, особенно на начальных порах.

Цитата: Ybr
А не могли бы по каждой кратко написать, в каком направлении мне искать информацию?
Идея в том, чтобы я не копал весь инет в поисках сам-не-знаю-чего, а искать прицельно то, что поможет решить задачу.


Собсно, я даже не знаю, что подсказать. Имхо, лабы решаются элементарно. Ничуть не сложнее седьмой.
Достаточно ввести в гугле что-то вроде односвязный список исходник с++ и в ссылках можно утонуть. Не знаю что проще: найти в этом море инфы нужное или написать код самому :).
Подсказки по последней лабе: скопировав класс танализ (пишу по-русски - шифруемся от препода :D), не забудьте поставить в конце точку с запятой ;. Для замены символов вполне естественно использовать метод replace класса string.

Цитата: Ybr
у меня проблема в С++ только одна, но большая: язык сложный, объемный. Каждую задачу можно решить несколькими способами. Какой из них самый простой я, естественно, не знаю.

Хех, у меня та же проблема... Я потому и помогаю, чтобы самому освоить что-то новое по ходу дела. С++ действительно очень объёмен, именно за это его любят и ненавидят. :cool:

15K
12 декабря 2009 года
Ybr
31 / / 19.03.2007
Огромная вам благодарность, koodeer, за такой подробный ответ. Еще хочу отметить очень дружественное настроение сообщения. В английском есть очень подходящее выражение: to be really into (smth). В нашем случае [FONT="Lucida Console"]smth = желание помочь[/FONT]. За такую моральную поддержку еще одно отдельное спасибо.
Цитата: koodeer
Собсно, я даже не знаю, что подсказать. Имхо, лабы решаются элементарно. Ничуть не сложнее седьмой.


Что ж. Раз просто, то сделаю сам. Хотя с ужасом вспоминаю, что седьмую лабу, первую часть, делал примерно 2 дня полных (с утра до вечера). Именно потому, что находил не ту информацию, которую надо (это к вопросу о [FONT="Lucida Console"]String^[/FONT] и [FONT="Lucida Console"]string[/FONT]).
В общем, с вашими подсказками поиск будет гораздо проще и эффективнее. Если столкнусь с «нерешаемыми» проблемами – очень надеюсь на вашу помощь здесь:).

15K
20 декабря 2009 года
Ybr
31 / / 19.03.2007
Здравствуйте!
Начал делать 10 лабу. Запнулся почему-то не на создании класса (с этим все гладко было), а в процессе кодинга.

Что делает нижеописанный метод: Определить, сколько раз в заданном предложении встречаются 3 одинаковых символа подряд (учитываем, что это могут быть 2 разных символа).

Замечание1: я решил сначала отдельно написать метод, а потом засунуть его в класс.
Замечание2: комментарии писал чисто для себя, не задумывался об их понятности. Поэтому если возникают вопросы - задавайте.

Код:
#include "stdafx.h"
#include "windows.h"
#include "stdio.h"
#include <conio.h>
#include "vector"
#include <string>
#include <iostream>
#include "locale"
#include <fstream>

using namespace std;

int main()
{
    setlocale(LC_ALL,"Russian");

    ifstream Input;//поток на ввод
    ofstream Output;//поток на вывод
    string s1;//заданная строка
    vector <char> M1;//содержит буквы, создающие искомые комбинации
    vector <int> M2;//содержит количество раз, которые встречаются эти комбинации

    Input.open("C:\\Users\\Михаил\\Desktop\\ДРП\\Lab10Help\\Input.txt");
    Output.open("C:\\Users\\Михаил\\Desktop\\ДРП\\Lab10Help\\Output.txt");
    getline(Input,s1);

    char buf2=s1.at(0), buf1=' ',buf3=' ';//buf2 - текущий символ, buf1 - предыдущий, buf3 - следующий
    char buf;
    unsigned short int i=0,j=0;//счетчики
    unsigned short int k=0;//считает 3 одинаковых символа
    unsigned short int z=0;//считает, скольок раз эта комбинация встретилась в предложении
    bool flag=true;

    for (i = 0 ; i < s1.length()-1 ; i++)
    {
                //находим 3 следующих подряд одинаковых символа
        buf2 = s1.at(i); buf3 = s1.at(i+1);
        if (buf2 == buf1 && buf2 == buf3) k++;//Если и предыдущий, и следующий символы равны текущему (buf2)
        buf1 = s1.at(i);

        [COLOR="DarkRed"]if (M1.empty() && k == 1) M1.at(0) = buf2; else[/COLOR]//Если M1 пуст и найдена искомая комбинация, то можно задать начальное значение для M1
        {
            if (k == 1)
            {
                for (j = 1 ; j < M1.max_size() ; j++)//определяем, встречался ли уже такой buf
                {
                    buf = M1.at(j);
                    if (buf == buf2) flag = false;
                }

                if (flag)//если да - добавляем новую букву в M1 и количество ее обнаружений (1) - в M2
                {
                    M1.push_back(buf2);
                    M2.push_back(1);
                }
                else M2.at(j) = M2.at(j) + 1;//если нет - то увеличиваем количество обнаружений в M2 соответствующего buf на 1
            }
        }
    }
   
    _getch();
    return 0;
}

Проблема появилась в строке [FONT="Lucida Console"][COLOR="DarkRed"]if (M1.empty() && k == 1) M1.at(0) = buf2; else[/COLOR][/FONT]. Выдается ошибка:
Цитата:
Необработанное исключение типа "System.Runtime.InteropServices.SEHException" произошло в Lab10Help.exe

Дополнительные сведения: Внешний компонент создал исключение.


То ли ему не нравится сравнение в [FONT="Lucida Console"]if ()[/FONT], то ли присваивание, следующее за [FONT="Lucida Console"]if[/FONT].

И вдогонку вопрос, не относящийся к теме сообщения: чем отличается объявление заголовочных файлов при использовании [FONT="Lucida Console"]""[/FONT] и [FONT="Lucida Console"]<>[/FONT] ? Т.е. чем отличается [FONT="Lucida Console"]#include <conio.h>[/FONT] от [FONT="Lucida Console"]#include "conio.h"[/FONT] ?

PS 2koodeer: Лабу 7 спокойно сдал преподу.

297
21 декабря 2009 года
koodeer
1.2K / / 02.05.2009
Цитата: Ybr

Проблема появилась в строке [FONT="Lucida Console"][COLOR="DarkRed"]if (M1.empty() && k == 1) M1.at(0) = buf2; else[/COLOR][/FONT].

То ли ему не нравится сравнение в [FONT="Lucida Console"]if ()[/FONT], то ли присваивание, следующее за [FONT="Lucida Console"]if[/FONT].


С помощью функции at можно работать лишь с уже существующими элементами вектора! Если элемента под номером n не существует, то нельзя к нему обратиться at(n).
В данном случае

 
Код:
if (M1.empty() && k == 1) M1.at(0) = buf2;

происходит попытка присвоения значения нулевому элементу в то время, как вектор пуст! Ведь условие empty() сработало.
Нужно переписать так:
 
Код:
if (M1.empty() && k == 1) M1.push_back(buf2);



Ещё ошибка:
 
Код:
for (j = 1 ; j < M1.[COLOR="Red"]max_size[/COLOR]() ; j++)

Надо:
 
Код:
for (j = 1 ; j < M1.size() ; j++)

Смотрим: max_size


В алгоритм не вникал, но заметил, что индекс j может выйти за размер вектора M2 здесь:
 
Код:
else M2.at(j) = M2.at(j) + 1;


Цитата: Ybr

И вдогонку вопрос, не относящийся к теме сообщения: чем отличается объявление заголовочных файлов при использовании [FONT="Lucida Console"]""[/FONT] и [FONT="Lucida Console"]<>[/FONT] ? Т.е. чем отличается [FONT="Lucida Console"]#include <conio.h>[/FONT] от [FONT="Lucida Console"]#include "conio.h"[/FONT] ?


Смотрим: Директива #include

297
22 декабря 2009 года
koodeer
1.2K / / 02.05.2009
Ybr, глянул ещё раз твой код на свежую голову. Зачем так сложно? Зачем заносить найденные вхождения трёх символов подряд в векторы? Потом придётся сооружать ещё циклы, чтобы уже из векторов эти данные извлечь и уже по ним обработать строку.

Вот что я наваял:
Код:
#include "stdafx.h"
#include <iostream> // cout
#include <fstream>  // ifstream, ofstream
#include <string>   // string, getline
#include <atlstr.h> // CString
#include <conio.h>  // getch()

using namespace std;

class _analiz
{
    char s;
public:
    _analiz(char s1) {s=s1;}
    int analiz()
    {
        //int i; // Нахуя?
        if (isdigit(s)!=0) return 1;//цифра
        if (islower(s)!=0) return 2;//нижн. регистр
        if (isupper(s)!=0) return 3;//верхн. регистр
        if (isspace(s)!=0) return 4;//пробел
        if (ispunct(s)!=0) return 5;//разделитель
        return 0;//др. символ
    }
};

void main()
{
    setlocale(LC_ALL, "Russian");

    string s; // нужна только для чтения из файла
    ifstream Input;
    Input.open("...");
    getline(Input, s);
    Input.close();

    CString cs(s.c_str()); // дальше работаем с CString
    cout << cs << endl; // исходная строка

    for (char ch='0'; ch<='9'; ++ch)
        cs.Remove(ch); // удаляем цифры
    cout << cs << endl; // строка после удаления цифр

    cs.Replace(' ', '_'); // меняем пробелы на подчёркивания
    cout << cs << endl; // строка после замены пробелов подчерками

    int count = 0; // счётчик вхождений трёх одинаковых символов подряд

    for (int i = 0; i < cs.GetLength() - 2; ++i)
    {
        char ch = cs.GetAt(i);
        if (ch == cs.GetAt(i+1) && ch == cs.GetAt(i+2))
        {
            _analiz t(ch);
            if (t.analiz() == 2) // нижний регистр
            {
                CString source(ch, 3); // что меняем (три одинаковых символа)
                CString dest( (char)_toupper(ch) ); // на что меняем
                count += cs.Replace(source, dest);
            }
            else if (t.analiz() == 3) // верхний регистр
            {
                CString source(ch, 3); // что меняем (три одинаковых символа)
                CString dest( (char)_tolower(ch) ); // на что меняем
                count += cs.Replace(source, dest);
            }
            else count++;
        }
    }
    cout << cs << endl; // строка после всех замен
    cout << "Count = " << count << endl;

    ofstream Output;
    Output.open("...");
    Output << cs;
    Output.close();

    getch();
}

Пришлось поломать голову, как сюда приткнуть рекомендованный класс. (Заменил в его названии первую буковку - шифруемся :D).

Применил в коде тип строки CString. В нём очень удобны, на мой взгляд, методы Remove и Replace.
Поясню их принцип работы: Remove удаляет все вхождения указанного символа из строки. Replace производит замену тоже во всей строке всех совпадений. Метод Replace возвращает количество произведённых замен, именно его и прибавляем к count.
15K
23 декабря 2009 года
Ybr
31 / / 19.03.2007
koodeer, спасибо большое за ответ. Что касается твоего варианта программы, то ты не учел, что может быть слово типа: "авпавпооорррпппооо". Результат должен быть примерно такой:
 
Код:
Комбинация с буквой "о" встретилась 2 раз
Комбинация с буквой "р" встретилась 1 раз
Комбинация с буквой "п" встретилась 2 раз

Либо я не понял твоего кода, и он учитывает этот момент тоже:) Я сделал так:
Код:
#include <stdafx.h>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <vector>
#include <string>
#include <iostream>
#include <locale>
#include <fstream>

using namespace std;

class Search
{
public:
    Search(string s);//Конструктор
    ~Search();//Деструктор
    //void DelNumber(s1);//удаление цифр
    //void Lowercase(s1);//если буквы нижнего регистра, заменить на верхнего
    //void Uppercase(s1);//если буквы верхнего регистра, заменить на нижнего
    //void ReplaceSpace(s1);//замена пробелов на знаки подчеркивания
    int Detect();//определить, сколько раз встречаются 3 одинаковых символа
private:
    string s1;//данная строка
};

Search::Search(string s)
{
    s1 = s;
}

Search::~Search()
{
}

int Search::Detect()
{
    vector <char> M1;//содержит буквы, создающие искомые комбинации
    vector <int> M2;//содержит количество раз, которые встречаются эти комбинации

    char buf2=s1.at(0), buf1=' ',buf3=' ';//buf2 - текущий символ, buf1 - предыдущий, buf3 - следующий
    char buf=' ';//буфер
    unsigned short int i=0,j=0;//счетчики
    unsigned short int k=0;//если найдено 3 одинаковых символа подряд, k = 1
    unsigned short int z=0;
    bool flag=true;

    for (i = 0 ; i < s1.length()-1 ; i++)
    {
        buf2 = s1.at(i); buf3 = s1.at(i+1);
        if (buf2 == buf1 && buf2 == buf3) k++;//Если и предыдущий, и следующий символы равны текущему (buf2)
        buf1 = s1.at(i);

        if (k == 1)
        {
            for (j = 0 ; j < M1.size() ; j++)//определяем, встречался ли уже такой buf
            {
                buf = M1.at(j);
                if (buf == buf2) {flag = false; z = j;}//если да, сохраняем номер соответствующей позиции в M1
            }

            if (flag)//если нет - то увеличиваем количество обнаружений (M2) соответствующего buf на 1
            {
                M1.push_back(buf2);
                M2.push_back(1);
            }
            else {M2.at(z) = M2.at(z) + 1;}
        }
        k = 0; flag = true;
    }

    cout << "В введенной фразе следующие символы удовлетворяют поставленному условию:\n";
    for (i = 0 ; i < M1.size() ; i++)
    {
        cout << "\nКомбинация с символом '" << M1.at(i) << "' встречается " << M2.at(i) << " раз";
    }
   
    return 0;
}

int main()
{
    setlocale(LC_ALL,"Russian");

    ifstream Input;//поток на ввод
    ofstream Output;//поток на вывод
    string s11;//заданная строка
   
    Input.open("C:\\Users\\Михаил\\Desktop\\ДРП\\Lab10\\Input.txt");
    Output.open("C:\\Users\\Михаил\\Desktop\\ДРП\\Lab10\\Output.txt");
    getline(Input,s11);
   
    Search analiz(s11);

    analiz.Detect();

    _getch();
    return 0;
}


PS Я вроде говорил, что препод позволил менять класс. Это я к тому, что мой класс в общем не особо похож на то, что было задано :)
297
24 декабря 2009 года
koodeer
1.2K / / 02.05.2009
Цитата: Ybr
koodeer, спасибо большое за ответ. Что касается твоего варианта программы, то ты не учел, что может быть слово типа: "авпавпооорррпппооо". Результат должен быть примерно такой:
 
Код:
Комбинация с буквой "о" встретилась 2 раз
Комбинация с буквой "р" встретилась 1 раз
Комбинация с буквой "п" встретилась 2 раз

Либо я не понял твоего кода, и он учитывает этот момент тоже:)


Нет, в том моём варианте подсчёта отдельных комбинаций не предусмотрено. Считается лишь их общее количество.

Цитата: Ybr
Я сделал так:


В твой код не вникал, могу лишь отметить неудачный нейминг векторов: M1 и M2 - такие названия совершенно ни о чём не говорят. Вот названия для функций выбраны довольно удачные.

Цитата: Ybr

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


Где такое было сказано?

Ну, если нет необходимости использовать никчёмный класс, то вот мой новый вариант, подсчитывающий отдельно количество вхождений 3 символов:

Код:
#include "stdafx.h"
#include <iostream> // cout
#include <fstream>  // ifstream, ofstream
#include <string>   // string, getline
#include <atlstr.h> // CString
#include <conio.h>  // _getch()
#include <vector>   // vector
#include <map>      // map
#include <locale>   // locale
using namespace std;

void main()
{
    setlocale(LC_ALL, "Russian"); // для вывода русских букв в консоли
    locale rus("Russian_Russia"); // для работы функций islower, isupper с русскими буквами

    string s; // нужна только для чтения из файла
    ifstream Input;
    Input.open("...");
    getline(Input, s);
    Input.close();

    CString cs(s.c_str()); // дальше работаем с CString
    cout << cs << endl; // исходная строка

    for (TCHAR ch='0'; ch<='9'; ++ch)
        cs.Remove(ch); // удаляем цифры
    cout << cs << endl; // строка после удаления цифр

    cs.Replace(' ', '_'); // меняем пробелы на подчёркивания
    cout << cs << endl; // строка после замены пробелов подчерками

    map<TCHAR, int> m;
    for (int i = 0; i < cs.GetLength() - 2; ++i)
    {
        TCHAR ch = cs.GetAt(i);
        if (ch == cs.GetAt(i+1) && ch == cs.GetAt(i+2))
        {
            if (islower(ch, rus)) // нижний регистр
            {
                CString source(ch, 3); // что меняем (три одинаковых символа)
                CString dest( (char)_toupper(ch) ); // на что меняем
                m[ch] = cs.Replace(source, dest);
            }
            else if (isupper(ch, rus)) // верхний регистр
            {
                CString source(ch, 3); // что меняем (три одинаковых символа)
                CString dest( (char)_tolower(ch) ); // на что меняем
                m[ch] = cs.Replace(source, dest);
            }
            else
            {
                m[ch]++; // считаем
                i += 2; // перепрыгиваем через одинаковые символы
            }
        }
    }
    cout << cs << endl; // строка после всех замен

    map<TCHAR, int>::iterator iter;
    for (iter = m.begin(); iter != m.end(); ++iter)
        cout << "Подряд 3 символа '" << iter->first << "' встретились " << iter->second << " раз" << endl;

    ofstream Output;
    Output.open("...");
    Output << cs;
    Output.close();

    _getch();
}

Код исправлен по сравнению с предыдущим и теперь при компиляции не выдаётся ни одного предупреждения.
Компилил в Visual Studio 2005. Проверял и Debug, и Release.
Ма-а-аленькая подсказка: в свойствах проекта обязательно выставить свойство Character set в значение Use Multi-Byte Character Set. Со значением Use Unicode Character Set программа будет работать неправильно. Причём сделать это нужно как в конфигурации Debug, так и Release.

PS: я однако отжог в комментариях ненужной переменной в прошлый раз :)
15K
25 декабря 2009 года
Ybr
31 / / 19.03.2007
Спасибо большое за прогу. Но есть один момент.
Цитата: koodeer
Ну, если нет необходимости использовать никчёмный класс, то вот мой новый вариант, подсчитывающий отдельно количество вхождений 3 символов:


koodeer, класс обязательно нужно использовать, но его можно менять по своему усмотрению.
Сможешь помочь переделать прогу? То есть понятно, что по сути появятся только 1) новые переменные, для передачи их методам-членам и 2) куски кода будут разбросаны по этим методам.
Но я никогда не работал с [FONT="Lucida Console"]CString[/FONT] и [FONT="Lucida Console"]map[/FONT], да и классы в новинку. И разбираться щас с этим воооще нереал.:confused:

Цитата: koodeer
PS: я однако отжог в комментариях ненужной переменной в прошлый раз


Все в порядке вещей:D

15K
25 декабря 2009 года
Ybr
31 / / 19.03.2007
Да, и забыл сказать, что я все еще не теряю надежды когда-нибудь самостоятельно сделать эту прогу:). На данный момент реализовал поиск комбинации из 3 символов. На мой взгяд, довольно изящно (уж точно лучше той каши, которая была в предыдущем моем мообщении). Есть 2 вопроса:
  1. Насколько хорошая реализация?
  2. В чем ошибка? (строку, которая выдает ошибку, я выделил в [FONT="Lucida Console"]коде[/FONT] жирным). То есть программа запускается, но на определенном этапе вылетает.
Код:
#include <stdafx.h>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <vector>
#include <string>
#include <iostream>
#include <locale>
#include <fstream>
#include <set>

using namespace std;

int main()
{
    setlocale(LC_ALL,"Russian");

    vector <char> M1;//содержит буквы, создающие искомые комбинации
    vector <int> M2;//содержит количество раз, которые встречаются эти комбинации
    ifstream Input;//поток на ввод
    ofstream Output;//поток на вывод
    string s1,s2;//заданная строка и ее копия  (вспомогательная)
    string substr;//подстрока
    string::iterator it1, it2;//итераторы
    unsigned short int i=0,z=0;//счетчики
    size_t found;//ищет вхождения подстроки substr
    char buf1, buf2;
    bool flag=true;

    Input.open("...");
    Output.open("...");
    getline(Input,s1); Input.close(); s2 = s1;

    for (it1 = s1.begin() ; it1 < s1.end() ; it1++)
    {
        for (i = 0 ; i < 3 ; i++) substr.push_back(*it1);//выделили подстроку

        found = s1.find(substr);
        if (found < s1.length())//если такая подстрока есть, то:
        {
            for (i = 0 ; i < M1.size() ; i++)//1. Определяем, встречалась ли уже такая подстрока substr
            {
                buf1 = M1.at(i); buf2 = substr.at(0);
                if (buf1 == buf2) {flag = false; z = i;}
            }

            if (flag)//2.1. Если НЕ встречалась - то записываем новую комбинацию в M1
            {
                M1.push_back(substr.at(0));
                M2.push_back(1);
            }
            else//2.2. Если встречалась - то увеличиваем количество обнаружений (M2) на 1
            {
                M2.at(z) = M2.at(z) + 1;
                flag = true;
            }
           
            s1.erase(found,3);
        }
        substr.clear();
    }

    cout << "Была введена следующая фраза:\n" << s2 << "\n\n";
    cout << "\nВ введенной фразе следующие символы удовлетворяют поставленному условию:";
    for (i = 0 ; i < M1.size() ; i++)
    {
        cout << "\nКомбинация с символом '" << M1.at(i) << "' встречается " << M2.at(i) << " раз";
    }

    _getch();
    return 0;
}
297
25 декабря 2009 года
koodeer
1.2K / / 02.05.2009
Цитата: Ybr

В чем ошибка?
...
То есть программа запускается, но на определенном этапе вылетает.

 
Код:
string::iterator it1, it2;//итераторы

for (it1 = s1.begin() ; it1 < s1.end() ; it1++)
{
    ...
    s1.[COLOR="Red"]erase[/COLOR](found,3);
    ...
}


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


Исчо адын вариант:

Код:
#include "stdafx.h"
#include <iostream> // cout
#include <fstream>  // ifstream, ofstream
#include <string>   // string, getline
#include <atlstr.h> // CString
#include <conio.h>  // _getch()
#include <vector>   // vector
#include <map>      // map
#include <locale>   // locale
using namespace std;

class tanaliz
{
    char s;
    locale loc;
public:
    tanaliz(char s1, locale loc1)
    {
        s = s1;
        loc = loc1;
    }
    int analiz()
    {
        if (isdigit(s, loc)!=0) return 1;//цифра
        if (islower(s, loc)!=0) return 2;//нижн. регистр
        if (isupper(s, loc)!=0) return 3;//верхн. регистр
        if (isspace(s, loc)!=0) return 4;//пробел
        if (ispunct(s, loc)!=0) return 5;//разделитель
        return 0;//др. символ
    }
};

void main()
{
    setlocale(LC_ALL, "Russian");
    locale rus("Russian_Russia");

    string s; // нужна только для чтения из файла
    ifstream Input;
    Input.open("...");
    getline(Input, s);
    Input.close();

    CString cs(s.c_str()); // дальше работаем с CString
    cout << cs << endl; // исходная строка

    for (TCHAR ch='0'; ch<='9'; ++ch)
        cs.Remove(ch); // удаляем цифры
    cout << cs << endl; // строка после удаления цифр

    cs.Replace(' ', '_'); // меняем пробелы на подчёркивания
    cout << cs << endl; // строка после замены пробелов подчерками

    map<TCHAR, int> m;
    for (int i = 0; i < cs.GetLength() - 2; ++i)
    {
        TCHAR ch = cs.GetAt(i);
        if (ch == cs.GetAt(i+1) && ch == cs.GetAt(i+2))
        {
            tanaliz t(ch, rus);
            if (t.analiz() == 2) // нижний регистр
            {
                CString source(ch, 3); // что меняем (три одинаковых символа)
                CString dest( (char)_toupper(ch) ); // на что меняем
                m[ch] = cs.Replace(source, dest);
            }
            else if (t.analiz() == 3) // верхний регистр
            {
                CString source(ch, 3); // что меняем (три одинаковых символа)
                CString dest( (char)_tolower(ch) ); // на что меняем
                m[ch] = cs.Replace(source, dest);
            }
            else
            {
                m[ch]++; // считаем
                i += 2; // перепрыгиваем через одинаковые символы
            }
        }
    }
    cout << cs << endl; // строка после всех замен

    map<TCHAR, int>::iterator iter;
    for (iter = m.begin(); iter != m.end(); ++iter)
        cout << "Подряд 3 символа '" << iter->first << "' встретились " << iter->second << " раз" << endl;

    ofstream Output;
    Output.open("...");
    Output << cs;
    Output.close();

    _getch();
}

Класс допилил, чтобы он работал с русскими буквами.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог