Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.04.2013, 19:05   #1
ndiezel
Новичок
Джуниор
 
Регистрация: 21.04.2013
Сообщений: 3
По умолчанию Более правильное решение

Есть одна задачка:
Цитата:
Разработчикам приложений время от времени приходится собирать регистрационные данные от
пользователей. При этом некоторые данные принято автоматически проверять на корректность. Мы
предлагаем вам проверить на корректность адрес электронной почты.
Будем считать, что корректный адрес устроен так: LOCAL@DOMAIN. Мы считаем, что он состоитиз части LOCAL, которая стоит до знака @, и части DOMAIN, которая стоит после него. Часть LOCAL состоит из одного или более
слов, которые отделяютcя друг от друга ровно одной точкой. Часть DOMAIN состоит из двух или более слов, которые отделяются друг от друга ровно одной точкой.
Каждое слово это последовательность символов, которая может состоять из маленьких и больших латинских букв, десятичных арабских цифр, а также дефиса "-" и знака подчёркивания "_".
Каждое слово состоит хотя бы из одного символа.

Формат входного файла
В единственной строке входного файла дана последовательность символов с кодами от 32 до 127.
В этой последовательности не более 100 символов.

Формат выходного файла
Выведите "YES", если содержимое входного файла является корректным адресом электронной почты. В противном случае выведите "NO".

Пример
postmaster@example.com YES
***@gmail.com NO
Я написал такое "лобовое" решение:
Код:
#include <iostream>
#include <string>

using namespace std;

int main()
{
	string a;
	cin >> a;
	bool local(false), point(false);
	int shet(0);
	for(int i = 0; i < a.length(); i++){
		if((a[i] >= 'a' && a[i] <= 'z') || (a[i] >= 'A' && a[i] <= 'Z')  || (a[i] >= '0' && a[i] <= '9') || a[i] == '-' || a[i] == '.' || a[i] == '_' || a[i] == '@'){
			if((i == a.length() - 1 && (a[i] == '.' || a[i] == '@')) || (i == 0 && (a[i] == '.' || a[i] == '@'))){
				cout << "NO";
				return 0;
			}
			if(a[i] == '.' && i != 0 && point == false){
				point = true;
				if(local == true)
					shet++;
				continue;
			}
			if(a[i] == '.' && i == 0 && point == false){
				cout << "NO";
				return 0;
			}
			if(a[i] == '.' && point == true){
				cout << "NO";
				return 0;
			}
			point = false;
			if(a[i] == '@' && local == false){
				if(a[i-1] == '.'){
					cout << "NO";
					return 0;
				}
				if(a[i+1] == '.'){
					cout << "NO";
					return 0;
				}
				local = true;
				continue;
			}
			if(a[i] == '@' && local == true){
				cout << "NO";
				return 0;
			}
		}
		else{
			cout << "NO";
			return 0;
		}
	}
	if(shet > 0)
		cout << "YES";
	else
		cout << "NO";
	return 0;
}
Не подскажите ли более простое решение, ибо это падает на паре тестов, да и эстетично выглядит жутко.
ndiezel вне форума Ответить с цитированием
Старый 21.04.2013, 19:36   #2
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,289
По умолчанию

Вроде все учел:
Код:
#include <iostream>
#include <string>
#include <cctype>

using namespace std;

int
isword(int c)
{
    return (isalnum(c) || c == '-' || c == '_');
}

int
main()
{
    string a;
    cin >> a;
    bool word(false), domain(false), address(true);
    int count = 0;
    for (auto i: a) {
        switch (word) {
            case false:
                if (!isword(i)) {
                    address = false;
                    break;
                } else {
                    word = true;
                    count += domain;
                };
                break;
            case true:
                if (i == '@') {
                    domain = true;
                    word = false;
                } else if (!isword(i)) {
                    word = false;
                    if (i != '.') {
                        address = false;
                    }
                }
        }
        if (!address) {
            break;
        }
    }
    if (!address || count < 2 || !domain || !word) {
        cout << "NO";
    } else {
        cout << "YES";
    }
}
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 21.04.2013 в 19:49.
BDA вне форума Ответить с цитированием
Старый 21.04.2013, 20:25   #3
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Вроде все учел
eto@ne@e-mail
Somebody вне форума Ответить с цитированием
Старый 21.04.2013, 20:46   #4
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,289
По умолчанию

Цитата:
Сообщение от Somebody Посмотреть сообщение
eto@ne@e-mail
Спасибо.
fixed
Код:
#include <iostream>
#include <string>
#include <cctype>

using namespace std;

int
isword(int c)
{
    return (isalnum(c) || c == '-' || c == '_');
}

int
main()
{
    string a;
    cin >> a;
    bool word(false), domain(false);
    int count(0);
    for (auto i: a) {
        if (word) {
             if (!isword(i)) {
                word = false;
                if (!domain && i == '@') {
                    domain = true;
                } else if (i != '.') {
                    break;
                }
            }
        } else {
            if (!isword(i)) {
                break;
            } else {
                word = true;
                count += domain;
            }
        }
    }
    if (count < 2 || !domain || !word) {
        cout << "NO";
    } else {
        cout << "YES";
    }
}
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 21.04.2013 в 20:51.
BDA вне форума Ответить с цитированием
Старый 21.04.2013, 20:56   #5
ndiezel
Новичок
Джуниор
 
Регистрация: 21.04.2013
Сообщений: 3
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Спасибо.
fixed
Этот вариант спотыкается об те же грабли, что и мой выше представленный. Возможно трабла в условии
ndiezel вне форума Ответить с цитированием
Старый 21.04.2013, 21:05   #6
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,289
По умолчанию

Замените "cin >> a;" на "getline(cin, a);".
Если поможет, и у Вас возникнет вопрос "почему?", то спрашивайте

UPD
Цитата:
Подозреваю, что там еще были пробелы, которые простой cin не ловил.
Точно
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 21.04.2013 в 21:20.
BDA вне форума Ответить с цитированием
Старый 21.04.2013, 21:18   #7
ndiezel
Новичок
Джуниор
 
Регистрация: 21.04.2013
Сообщений: 3
По умолчанию

Действительно заработало.
Подозреваю, что там еще были пробелы, которые простой cin не ловил.
ndiezel вне форума Ответить с цитированием
Старый 21.04.2013, 21:32   #8
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Код:
#include <iostream>
#include <regex>
#include <string>

using namespace std;

int main()
{
	string a;
	getline(cin, a);
	regex regexEmail(R"([\w_-]+(\.[\w_-]+)*@[\w_-]+(\.[\w_-]+)+)");
	cout << (regex_match(a, regexEmail) ? "YES" : "NO");
}
Если настанет тот день, когда компиляторы и их библиотеки это переварят...
Somebody вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не правильное отображение в ie stainer HTML и CSS 3 07.04.2013 14:07
Правильное управление jetei Gamedev - cоздание игр: Unity, OpenGL, DirectX 3 01.02.2012 19:32
Правильное добавление маГГ85 SQL, базы данных 5 14.01.2012 23:26
Решение правильное маГГ85 PHP 2 15.12.2011 21:30
Какое программирование в наше время более востребовано и более рентабельно? iukash Свободное общение 18 29.10.2009 13:02