Witam.
Znacie jakiś szybki algorytm, ktory zliczałby mi literki w wyrazie i układał w porządku alfabetycznym?
np. Mama ma okres
a=3, e=1, k=1, m=2, o=1, s=1, r=1, M=1
W jakim alfabecie 'M' jest po 's'?
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
string s;
char temp;
int a,b;
cout<<"Podaj wyraz: ";
cin>>s;
for(unsigned int i=0; i<s.length()-1; i++)
{
for(unsigned int j=0; j<s.length()-1; j++)
{
a = (int)s[j];
b = (int)s[j+1];
if(a>b)
{
temp=s[j];
s[j]=s[j+1];
s[j+1]=temp;
}
}
}
cout<<"Dlugosc wyrazu = "<<s.length()<<endl;
cout<<"Wyraz z posortowanymi literami: "<<s;
return 0;
}
Witam,
Niestety rozwiązanie wyżej będzie działać tylko w przypadku pojedynczych wyrazów, żeby zadziałało na całe zdania należy zmienić linijkę
cin >> s;
na
getline(cin, s);
Dalej żeby dobrze pokazywało ilość liter będzie trzeba się pozbyć spacji i wszystkich znaków interpunkcyjnych. Na końcu łatwo już policzyć ile jest poszczególnych znaków.
Dzięki, pomogło:)
Zadanie jeszcze nie jest rozwiązane. Jak wpiszemy "wyraz" sśŚdD, to program wypisze ŚśDds. Zupełnie nie przypomina to porządku alfabetycznego.
"Zwykłe" porównanie większy/mniejszy będzie się różnie (w zależności od kompilatora i kodowania) zachowywać dla polskich znaków. Opracuj własne porównanie, np. jako funkcję zwracającą 1, -1 lub 0 (większe, mniejsze, równe) i wywołuj w miejscu if (a > b)
w postaci if (porownaj(a, b) == 1
.
#include<iostream>
#include<cstring>
using namespace std;
main(){
short w, znak[255];
string text;
for(short i = 32; i <= 122; i++) znak[i] = 0;
cin >> w;
getline(cin, text);
for(short i = 0; i < w; i++){
getline(cin, text);
for(short j = 0; j < text.length(); j++)
znak[(int)text[j]]++;
}
for(short i = 97; i <= 122; i++){
if(znak[i]==0 || char(i)==' ') continue;
else cout << char(i) << " " << znak[i] << endl;
}
for(short i = 65; i <= 90; i++){
if(znak[i]==0 || char(i)==' ') continue;
else cout << char(i) << " " << znak[i] << endl;
}
};
Ma ktoś pomysł na zgrabniejszy i jędrniejszy algorytm? Pozdro.
A co ten program robi? Podobny efekt (ale prościej, bez konieczności naciskania Ctrl-C) uzyskuję bardziej zwartym programem
int main()
{
return 0;
}
Podaje link do treści zadania https://pl.spoj.pl/problems/JZLICZ/
Jak ktoś ma lepszy algorytm, to fajnie gdyby się nim podzielił :)
Lubie cycki :) napisał(a)
for(short i = 32; i <= 122; i++) znak[i] = 0;
Auć.... To w C++ nie można używać memset()/bzero()?
Chcesz to masz :P http://ideone.com/RQUyc
@Edit - ok algorytm jako taki jest ;D
Ale lubię cycki już podał dobry algo, więcej kombinować nie trzeba. Zrobiłem krótszy kod w Scali, ale nie przeszedł (za długo się wykonywał).
object Main extends Application {
val counts = new Array[Int](128)
(0 until readInt).foreach(i => readLine.foreach(counts(_) += 1))
counts.zipWithIndex.filter(x => x._1 != 0 && x._2 != ' ').sortBy(_._2 ^ 32).
foreach(t => printf("%c %d\n", t._2 % 128, t._1))
}
std::string str;
std::getline(cin, str);
std::string str_cp = str;
std::sort(str_cp.begin(), str_cp.end());
std::unique(str_cp.begin(), str_cp.end());
std::remove_if(str_cp.begin(), str_cp.end(), isspace);
for(std::string:iterator it = str_cp.begin; it != str_cp.end(); ++it)
std::cout << *it << ' ' << std::count(str.begin(), str.end(), *it);
Powinno zadziałać.
Hej. Uczę się programować w pythonie i czy ten kod jest dobry do zliczenia literek ?
def nSkrypt(String):
for i in range(65, 123):
ile = 0
for j in range(0, len(String)):
if chr(i) == String[j]:
ile += 1
if ile > 0:
print chr(i), " ", ile
x = nSkrypt("biedronka bez ogonka")
Nie. Działać pewnie działa, ale omiatasz ciąg znaków kilkadziesiąt razy bez sensu. Użyj słownika i przeskanuj ciąg jeden raz.
- Bardzo nieoptymalnie - wielokrotnie czytasz ten sam String.
- Nie spełnia warunków zadania - najpierw małe litery, potem duże.
- Niepotrzebna spacja w print.
Poprawiłem (2) i wprowadziłem małe uproszczenie.
def nSkrypt(String):
for i in range(97,123):
ile = 0
for c in String:
if chr(i) == c:
ile += 1
if ile > 0:
print chr(i),ile
for i in range(65,90):
ile = 0
for c in String:
if chr(i) == c:
ile += 1
if ile > 0:
print chr(i),ile
x = nSkrypt("Biedronka bez ogonka")
A nie lepiej tak?
inp = u"Ala ma kota, a kot ma Alę"
chars = {}
for char in inp:
if not chars.has_key(char): chars[char] = 0
chars[char] += 1
for char in reversed(sorted(chars.keys())):
print("{0} - {1}".format(char.encode('UTF-8'), chars[char]))
Dobra rzecz do dictionary comprehension (jak zwykle sesja iPythona):
In [1]: from itertools import groupby
In [2]: from string import letters
In [3]: s = 'to jest jakis testowy string!!1111oneoneone'
In [4]: { c: len(list(g)) for c, g in groupby(sorted(s)) if c in letters }
Out[4]:
{'a': 1,
'e': 5,
'g': 1,
'i': 2,
'j': 2,
'k': 1,
'n': 4,
'o': 5,
'r': 1,
's': 4,
't': 5,
'w': 1,
'y': 1}
Up + format + zarośla
from itertools import groupby
from string import letters
s = u'to jest jakis testowy string!!1111oneoneone z pąlskimi ząrąślami'
print({ c: len(list(g)) for c, g in groupby(sorted(s)) if c in unicode(letters) + u'ąćęłńóśźżĄĆĘŁŃÓŚŹŻ' })
Jak wrzucę te wasze programy wprost do Pythonowego REPLa to mi wyświetla statystyki w złej kolejności. Odpalcie te swoje programy na ideone.com co bym widział, że to dobrą kolejność daje :) Pamiętajcie, że duże litery mają być PO małych literach.
Poprawiłeś wyjście? Bo przykłady z itertools printują postać znakową słownika, co dla Ideone może być pewnym zaskoczeniem.
piotrek@p5q-pro:~/Pulpit$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from itertools import groupby
>>> from string import letters
>>>
... s = u'to jest jakis testowy string!!1111oneoneone z pąlskimi ząrąślami'
>>> print({ c: len(list(g)) for c, g in groupby(sorted(s)) if c in unicode(letters) + u'ąćęłńóśźżĄĆĘŁŃÓŚŹŻ' })
{u'a': 2, u'e': 5, u'g': 1, u'i': 5, u'k': 2, u'j': 2, u'm': 2, u'l': 2, u'o': 5, u'n': 4, u'p': 1, u's': 5, u'r': 2, u't': 5, u'w': 1, u'y': 1, u'\u0105': 3, u'\u015b': 1, u'z': 2}
>>> s = u'ala ma kota Ola ma psa'>>> print({ c: len(list(g)) for c, g in groupby(sorted(s)) if c in unicode(letters) + u'ąćęłńóśźżĄĆĘŁŃÓŚŹŻ' })
{u'a': 7, u'k': 1, u'm': 2, u'l': 2, u'o': 1, u'p': 1, u's': 1, u'O': 1, u't': 1}
>>> { c: len(list(g)) for c, g in groupby(sorted(s)) if c in letters }
{u'a': 7, u'k': 1, u'm': 2, u'l': 2, u'o': 1, u'p': 1, u's': 1, u'O': 1, u't': 1}
>>>
Spróbuj to:
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from itertools import groupby
from string import letters
from sys import stdin
# To niżej to jest jedna linia!
for i in sorted({ c: len(list(g)) for c, g in groupby(sorted(stdin.readline().decode('utf-8'))) if c in unicode(letters) + u'ąćęłńóśźżĄĆĘŁŃÓŚŹŻ' }.items(), lambda x,y: cmp(x[0],y[0]) if (y[0].islower() and x[0].islower()) or (y[0].isupper() and x[0].isupper()) else cmp(y[0],x[0])): print('{0} {1}'.format(i[0].encode('utf-8'), i[1]))
Nie wiem czy przejdzie, bo cmp() szereguje polskie zarośla za alfabetem ASCII.
Kumashiro, dlaczego na siłę próbujesz z Pythona zrobić Perla? Jak już chcesz krzaki to coś takiego:
from itertools import izip, count
letters = "aąbcćdeęfghijklłmnoóprsśtuwyzźżAĄBCĆDEĘFGHIJKLŁMNOÓPRSŚTUWYZŹŻ"))
lookups = dict(izip(letters, count()))
# linia = ...
data = { c: len(list(g)) for c, g in groupby(sorted(linia)) if c in lookups }
for char in sorted(data, key=lookups.get):
print '%s %d' % (char, data[char])
ofidyfil napisał(a)
Kumashiro, dlaczego na siłę próbujesz z Pythona zrobić Perla?
Bo lubię wyzwania, a "standardowy" Python jest nudny... ;)
To trzeba było wykorzystać czysty rachunek lambda + lambda wyrażenia i nic więcej :P
Narzuciłeś kierunek na itertools, ja tylko dopisuję ;)
Oj, nie narzekaj. Jest środa wieczór, trzeba zakończyć pierwszą połowę tygodnia fun'em, bo od jutra przyspieszamy do weekendu :D