Удалить повторяющиеся элементы из строки
Имеется строка
q = 'Бег 300 м Бег 300 м Бег 300 м'
Необходимо удалить повторяющиеся части строки, чтобы получить
q = 'Бег 300 м'
Пыталась делать через множество:
qw = set(q.split())
print(' '.join(qw))
>>> 300 м Бег
Но там меняется порядок слов, что не является правильным решением
P.S. Если имеется строка
q = 'Бег 300 м Бег 600 м Бег 300 м'
то должно получиться
>>> 'Бег 300 м Бег 600 м'
Если имеется строка
q = 'Бег 300 м Ходьба 300 м Бег 300 м'
то должно получиться
>>> 'Бег 300 м Ходьба 300 м'
Ответы (4 шт):
Автор решения: Space Researcher
→ Ссылка
финальный список = []
исходный список разбить на подсписки по 3 элемента, где в состав 3 элементов входит(упреждение дистанция единица измерения)//будем называть каждый такой подсписок тройкой
цикл по исходному списку:
взять новую тройку исходного списка
есть ли новая тройка в финальном списке?
да - пропустить тройку,
нет - добавить в финальный список
вывести финальный список
Автор решения: CrazyElf
→ Ссылка
Если формат искомых подстрок стабильный "слово число слово", то можно через регулярки решить:
import re
def search(text):
rx = re.compile(r'\w+\s+\d+\s+\w+')
return ' '.join(set(rx.findall(text)))
assert search('Бег 300 м Бег 300 м Бег 300 м') == 'Бег 300 м'
assert search('Бег 300 м Бег 600 м Бег 300 м') == 'Бег 300 м Бег 600 м'
Автор решения: Влад Гаврилюк
→ Ссылка
Я не изучал python, поэтому написал алгоритм на языке который знаю (C#), может натолконет на мысль, или кто-то сможет написать на нужном:
static void Main(string[] args)
{
string h_ = "Бег 300 м Бег 300 м Ходьба 300 м";
List<string> l_ = h_.Split(' ').ToList(); // разбиваем на массив
List<string> j_ = new List<string>(); // список для выражений, которые дублируются
string search_ = "";
bool have_ = false;
for (int i = 0; i < l_.Count; i++) // перебираем все элементы
{
if (have_) search_ += $" {l_[i]}"; // если мы ищем строку то добавляем следующее слово
else search_ = l_[i]; // если нет, то только данное слово будет искаться
int el_ = Count(h_, search_); // получаем количество вхождений строки
if (el_ > 1) { have_ = true; } // если больше нуля то продолжаем искать
else // если нет то проверяем наша строка для поиска больше одного слова
{
var g_ = search_.Split(' ');
if (g_.Length > 1)
{
var els_ = g_[..^1]; // выбираем до предпоследнего
var str_ = String.Join(" ", els_);
////это как дополнение не обязательно, для удаления 300 м
bool haveinres_ = false; // наличие нашей строки в уже добавленных строках
foreach (var in_ in j_)
{
if (in_.Contains(str_)) haveinres_ = true; // если есть то меняем
}
if (!haveinres_) j_.Add(String.Join(" ", els_));
/////////////////////
}
have_ = false;
}
}
string elms_ = String.Join(" ", j_); // все повторяющиеся элементы
Console.WriteLine(h_);
Console.WriteLine(elms_);
Console.ReadKey();
}
static int Count(string string_, string substring_)
{
int i_ = 0;
int index = 0;
while (index != -1)
{
index = string_.IndexOf(substring_, i_ > 0 ? ++index : 0);
if (index != -1) i_++;
}
return i_;
}
Автор решения: Pavel Serdukov
→ Ссылка
Лишние принты можно убрать. Как-то так вышло. Ждем лучших вариантов.
q = 'Забег 300 м Бег 300 м Ходьба 300 м Бег 300 м Плавание 300 м'
print(len(q))
list_ = []
list_t = []
total = q.split(' ')
print('TOTAL', total)
print(len(total[0]))
for n in range(len(q)):
if total != []:
for i in range(3):
list_.append(total.pop(0))
print('total', total)
print('list_', list_)
list_t.append(list_)
list_ = []
print('\nlist total', list_t)
for i in range(len(list_t)-1):
if list_t[i] not in total:
total.append(list_t[i])
print('TOTAL', total)