zliczanie literek - algorytm?

0

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

0

W jakim alfabecie 'M' jest po 's'?

1
#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;
}
1

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.

0

Dzięki, pomogło:)

0

Zadanie jeszcze nie jest rozwiązane. Jak wpiszemy "wyraz" sśŚdD, to program wypisze ŚśDds. Zupełnie nie przypomina to porządku alfabetycznego.

0

"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.

0
#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.

0

A co ten program robi? Podobny efekt (ale prościej, bez konieczności naciskania Ctrl-C) uzyskuję bardziej zwartym programem

int main()
{
    return 0;
}
0

Podaje link do treści zadania https://pl.spoj.pl/problems/JZLICZ/
Jak ktoś ma lepszy algorytm, to fajnie gdyby się nim podzielił :)

0
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()?

0

Chcesz to masz :P http://ideone.com/RQUyc

0

@Edit - ok algorytm jako taki jest ;D

0

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))
}
2
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ć.

0

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")
          
0

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.

0
  1. Bardzo nieoptymalnie - wielokrotnie czytasz ten sam String.
  2. Nie spełnia warunków zadania - najpierw małe litery, potem duże.
  3. 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")
0

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]))
0

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}
0

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'ąćęłńóśźżĄĆĘŁŃÓŚŹŻ' })
0

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.

0

Poprawiłeś wyjście? Bo przykłady z itertools printują postać znakową słownika, co dla Ideone może być pewnym zaskoczeniem.

0
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}
>>> 
0

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.

0

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])
0
ofidyfil napisał(a)

Kumashiro, dlaczego na siłę próbujesz z Pythona zrobić Perla?

Bo lubię wyzwania, a "standardowy" Python jest nudny... ;)

0

To trzeba było wykorzystać czysty rachunek lambda + lambda wyrażenia i nic więcej :P

0

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

1 użytkowników online, w tym zalogowanych: 0, gości: 1