Partage
  • Partager sur Facebook
  • Partager sur Twitter

fonction qui compte le nombre de fois qu'une lettr

9 juin 2015 à 15:11:45

Bonjour,

Je voudrais faire une fonction qui compte le nombre de fois qu'une lettre apparait dans un mot.  il ne faut pas faire de distinction entre minuscule et majuscules.

voici mon programme entier (ne pas tenir compte de l'autre fonction avec les nombres)

Il faut bien tout d'abord parcourir la chaine de caractère ou la comparée à l'aide d'une boucle "for" et ensuite rechercher le nombre fois où la lettre a été trouvée ?

Merci de votre aide.

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

int Menu()
{
	int choix;
		cout << "Voulez-vous : " << endl;
		cout << "1. Effectuer des operations arithmetiques " << endl;
		cout << "2. Manipuler une chaine de caracteres : " << endl;
		cout << "0. Quitter le programme : " << endl;
		cout << "Votre choix :  "<< endl;
		cin >> choix;
	return choix;
}
float OP(float a, float b)
{
	float res;
	cout << "Entrez deux nombres entiers : ";
	cin >> a >> b;
	while((a<-20||a>20)||(b<-20||b>20||b==0))
	{
		cout << "Vous devez entrez un nombre compris entre -20 et 20" << endl;
		cout << "Entrez a nouveau deux nombres : " << endl;
		cin >> a >> b;
	}
	res=a+b;
	cout << res << endl;
	res=a/b;
	cout << res << endl;
	return res;
}
char CR(char l[], char m[])
{
	int i, nombre_de_lettre=0;
	cout << "Saisissez un mot : ";
	cin.ignore();
	gets(m);
	cout << "Saisissez une lettre de l'alphabet : ";
	gets(l);
	for(i=0;i<strlen(m);i++)
	{
		if(strcmp(m,l)==0)
		{
			nombre_de_lettre++;
		} 
	}
	cout << nombre_de_lettre << endl;
	return i;
}
int main()
{
	int choix;
	int a=0,b=0;
	char m[51],l[51];
	do
	{
		choix=Menu();
		switch(choix)
		{
		case 1 : OP(a,b);
			break;
		case 2 : CR(l,m);
			break;
		}
	}while(choix!=0);
	return 0;
}
  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 15:22:30

Salut,

Je ne comprends pas bien ta question :

En gros là ton truc marche mais fait une distinction entre minuscules et majuscules, et tu voudrais que ce ne soit pas le cas ?

La méthode que tu utilises me paraît bien, en tous cas : avoir un compteur de lettres, tu parcours ton mot lettre à lettre et tu vérifies à chaque fois si la lettre que tu regardes est la même que celle qu'a entrée l'utilisateur, et si oui alors tu incrémentes le compteur.

Pour ne pas faire de distinction entre minuscule et majuscule, la chose que tu peux faire c'est utiliser la fonction toupper() (ou tolower() pour les minuscules ça ne change rien) :

Ligne 43, tu fais du coup 

if(strcmp(toupper(m),toupper(l))==0)

De cette façon, tu ne te soucies pas de la casse puisque tu mets tout en majuscules.

Enfin, tu fais le test entre deux majuscules, mais ni le mot ni la lettre entrés par l'utilisateur ne sera modifié par la fonction. ;)

Pour te servir de toupper() ou tolower(), il te faut inclure <ctype.h>

-
Edité par eldoir 9 juin 2015 à 15:23:48

  • Partager sur Facebook
  • Partager sur Twitter
Heureux l'étudiant qui, comme la paisible rivière, suit toujours son cours sans jamais quitter son lit.
9 juin 2015 à 15:28:01

C'est ça que je dois faire : 

Le problème c'est que quand je tape un mot il m'affiche le nombre de lettre qu'il y a dans tout le mot, or moi je veux taper une lettre et qu'il me dise combien de fois la lettre a été trouvée.

Fonctionnalité

Il faut demander à l'utilisateur de saisir un mot et une lettre de l'alphabet. Le programme doit indiquer combien de fois la lettre a été trouvée dans le mot. Si elle n'a pas été trouvée, le message "La lettre x n'a pas été trouvée dans le mot xxxxx" doit être affiché.

Fonction

Il faut écrire une fonction qui compte le nombre de fois qu'une lettre apparait dans un mot. Attention, il ne faut pas faire de dinstinction entre minuscule et majuscule.

Entrées

La lettre à rechercher

Le mot dans lequel effectuer la recherche

Sorties

Le nombre de fois que la lettre a été trouvée dans le mot

Il faudra donc rechercher 2 lettres à chaque fois dans le mot : la lettre minuscule et la lettre majuscule correspondante. Il y a un écart de "32" entre une lettre majuscule et une lettre minuscule. Par exemple, le code ASCII de "a" est 97, alors que le code ASCII de "A" est 65.

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 15:39:46

strlen ? strcmp ? char[] ? Et c'est quoi ces noms de fonctions ?

Là c'est juste du C tout moche.

Sinon :

#include <clocale>

int count_letter(char letter, std::string const& str) {
  letter = std::tolower(letter);
  size_t count {};
  for (auto l : str) {
    if (std::tolower(l) == letter) {
      count++;
    }
  }
  return count;
}

-
Edité par Emrak 9 juin 2015 à 15:40:31

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 15:42:14

Salut,

Je commence par te faire une liste de ce qui devrait être "interdit" en C++ :

  • Chaînes de caractères de type char[n] : on utilise std::string.
  • Les fonctions strlen et strcmp : on utilise les foncions de std::string.
  • Les prédéclarations de variables : déclare-les le plus tard possible.
En passant, donne des meilleurs noms à tes objets, parce que a, b, m, l ça ne veut rien dire pour nous.

A propos de ta question : pour compter le nombre d'occurrence d'un caractère dans une chaîne, il ne faut pas comparer la chaîne entière avec un caractère (ce que tu fais pourtant avec strcmp(m,l) ). D'ailleurs, le type de l ne doit pas être une chaîne, mais un caractère.

Il y a deux solutions :

  • Utiliser une range-based for pour parcourir ta chaîne et incrémenter une variable à chaque occurrence de la lettre cherchée (ce sur quoi tu t'es basé). Voir la réponse d'Emrak.
  • Supprimer toutes les occurrences de la lettre, puis retourner la différence de taille entre la chaîne originiale et la chaîne modifiée (un peu plus compliqué, penser à utiliser std::remove_if).

Pour que ça soit indépendant du fait que la chaîne soit en majuscule ou non, soit tu convertis toute la chaîne en majuscule/minuscule, soit tu teste chaque fois le même caractère une fois en majuscule, une fois en minuscule.

-
Edité par Olybri 9 juin 2015 à 15:43:31

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 15:44:19

c'est comme ça que j'apprends le c++ en cours 

le strlen il permet de compter le nombre de mot dans une chaine et strcmp de comparer les chaines, par exemple je met pas de std:: je met using namespace std au début 

je vais essayer le code proposé 

merci

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 15:44:20

Ajoute std::count_if et ca sera parfait

const auto count = std::count_if(begin(s), end(s), 
    [letter](char c){ return (std::tolower(c) == letter; });

-
Edité par gbdivers 9 juin 2015 à 15:44:40

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 15:46:12

Oui mais si il fait ça son prof va lui mettre 0 en disant que c'est pas du C++ :-° Parce qu'un gusse qui apprend C++ à ses élèves à coups de strlen/cmp et autre conneries, voilà quoi.
  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 15:47:22

Ah, l'énoncé vous parle du code ASCII ? Ben on va le faire avec le code ASCII alors :

'A' vaut en valeur entière 65,

'a' vaut 97,

Donc 'a'-32 vaut 'A'.

C'est comme ça que tu peux te passer des fonction toupper() et tolower() et faire directement avec le code ASCII ;)

Pour ce qui est de l'énoncé, il te demande de faire une fonction qui prend 2 paramètres : le mot dans lequel rechercher, et la lettre à rechercher.

Tu as bien pris cette consigne en compte mais je crois que tu n'as pas bien compris l'intérêt de faire ça :

L'intérêt, c'est d'arriver dans la fonction en connaissant déjà le mot et la lettre à utiliser;

Donc, ce n'est pas à la fonction de s'occuper de la saisie. Là, il est assez clair que l'énoncé te demande de le faire avant d'appeler la fonction.

Et enfin, pour ton problème, c'est parce que (et je ne l'avais pas vu au premier abord) tu fais ton test de strcmp entre m et l, sauf que m est un mot... et non pas une lettre ! Pour avoir accès à la i-ème lettre du mot m, tu dois écrire m[i].

Donc ligne 43 ton strcmp doit être, en corrigeant ce que je viens de te dire et en prenant en compte les minuscules et majuscules :

if((l >= 'a' && strcmp(m[i],l) == 0) || (strcmp(m[i], l+32) == 0))

En gros : si la lettre que je recherche est une minuscule, alors je la compare avec m[i]. Si ça foire, c'est peut-être parce que soit m[i] était en majuscule, soit c'était ma lettre qui était en majuscule, donc dans la deuxième partie de ma condition je fais le test entre majuscules : "l+32" est une opération tout à fait autorisée même si l est de type char, puisqu'un char est finalement un bête int mais avec une valeur comprise entre 0 et 255.

-
Edité par eldoir 9 juin 2015 à 15:48:10

  • Partager sur Facebook
  • Partager sur Twitter
Heureux l'étudiant qui, comme la paisible rivière, suit toujours son cours sans jamais quitter son lit.
9 juin 2015 à 15:54:33

http://image.noelshack.com/fichiers/2015/24/1433858029-erreur.png

Le problème c'est qu'il me met une erreur

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 15:59:38

Vire ces affreux strlen et strcmp, nom de nom !

Utilise std::string (header <string>)

std::string str = "hello";
size_t len = str.size();
if (str == "hello") {
  std::cout << "les chaines sont egales";
}

Essaie de comprendre ce que tu fais et d'où vient l'erreur. Tu n'apprendras jamais sinon.

-
Edité par Emrak 9 juin 2015 à 16:00:18

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 16:01:12

dav1994 a écrit:

c'est comme ça que j'apprends le c++ en cours 

Aah les profs à l'école, toujours un plaisir :)

  • Partager sur Facebook
  • Partager sur Twitter

git is great because Linus did it, mercurial is better because he didn't.

9 juin 2015 à 16:32:30

Moi aussi je prefere les solutions qui sont plus longues, plus complexes et avec plus d'erreurs que les solutions simples, en une ligne et sans erreur.

Sinon, il faudrait penser a lire la doc de strcmp, c'est fait pour comparer des chaines style C, pas des caractères un par un.

Allez, puisque le but est d’écrire du code C sur le forum C++, allons y :

size_t CR(const char* l, const char* m) {
    size_t count = 0;
    while (l != '\0' || m != '\0') {
        assert((*l > 64 && *l < 91) || (*l > 96 && *l < 123));
        assert((*m > 64 && *m < 91) || (*m > 96 && *m < 123));
        if (*l == *m || (*l)+32 == *m || *l == (*m)+32) {
            ++count;
        }
    }
    return count;
}

Mais je suis sur qu'en recherchant un peu, il doit être possible d’écrire du C++ en plus moderne que cela.

-
Edité par gbdivers 9 juin 2015 à 16:33:19

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 16:45:03

Attention, je ne cherche pas à vous contredire, vous avez tout à fait raison à propos de l'enseignement, tout ça tout ça,

Mais ce n'est pas en venant tous ici cracher sur l'enseignement dépassé des profs en matière de prog qui fera avancer les choses;

Je ne crois pas que donner des solutions plus compliquées que ce qui est attendu, ou n'utilisant pas les formules attendues et pourtant vues en cours, ce soit rendre service à dav1994.

Donc je pense que le mieux à faire, c'est juste de rester en accord avec son prof quelle que soit sa méthode d'enseignement, et juste le mettre au courant que ce n'est pas la meilleure manière de faire :)

Si dav1994 veut poursuivre dans cette voie, à savoir la programmation, alors il aura bien le temps d'apprendre à la dure ;)

-
Edité par eldoir 9 juin 2015 à 16:47:41

  • Partager sur Facebook
  • Partager sur Twitter
Heureux l'étudiant qui, comme la paisible rivière, suit toujours son cours sans jamais quitter son lit.
9 juin 2015 à 16:50:45

Remarque : on ne critique pas uniquement les profs qui ne savent se mettre a jour. On critique avant tout le fait d'utiliser des solutions qui posent problème.

La preuve : ma remarque concernant strcmp t'est destiné, tu l'utilises sur des char au lieu de char[]. Et au contraire, tu utilises toupper et tolower sur des char[] au lieu de char.

Et j'ai oublié d'en parler, mais les critiques visent aussi ceux qui recopient des codes sans essayer de les comprendre. En particulier en recopiant les erreurs que tu as fait dans tes codes.

Tu vois que l'on ne critique pas que les profs :)

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 18:55:58

eldoir a écrit:

Je ne crois pas que donner des solutions plus compliquées que ce qui est attendu, ou n'utilisant pas les formules attendues et pourtant vues en cours, ce soit rendre service à dav1994.

Compliquées ?

  • En quoi str.size() est plus compliqué que strlen(str) ?
  • En quoi str1 == str2 est plus compliqué que strcmp(str1, str2) ?
  • En quoi for(auto c : str) est plus compliqué que int i; for(i = 0; i < strlen(str); ++i) ?

Je veux bien que la méthode avec std::count_if  (d'ailleurs j'avais plus pensé à cette fonction quand j'ai posté ^^ ) soit un peu plus dur à comprendre au début, mais même sans, il vaut mieux directement commencer à prendre de bonnes habitudes (std::string au lieu de char[n], range based-for, entre autres). Ce que je n'ai pas fait, et j'en ai souffert.

-
Edité par Olybri 9 juin 2015 à 18:56:26

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 19:24:04

Olybri a écrit:

avec std::count_if  (d'ailleurs j'avais plus pensé à cette fonction quand j'ai posté ^^ ) soit un peu plus dur à comprendre au début

Non, je me revolte, je m'insurge contre cette infamie. Il faut interdire le for du C++. D'ailleurs, je suis sur que si l'on fait une recherche sur un internet a propos de bannir le for du C++, quelqu'un de très bien, très beau et très fort a déjà du en parler !

Plus sérieusement, il ne faut pas oublier que nos connaissances et habitudes influencent notre perception. Si on regarde objectivement :

  • for indique que l'on va parcourir quelque chose, "count" indique que l'on va compter quelque chose. La second syntaxe est beaucoup plus informative.
  • le début et la fin d'un tableau sont obtenu avec v[0] et v[size-1] dans un cas et avec begin(v) et end(v) dans le second. La première écriture n'est pas naturellement compréhensible (voir le nombre de débutants qui font l'erreur), c'est une simple convention arbitraire (ou presque). Encore une fois, la seconde syntaxe est beaucoup plus explicite.

La seule difficulté est l'utilisation de la fonction lambda dans le second cas. Mais c'est une "difficulté" en premier lieu parce que c'est présenté comme une syntaxe exotique et donc vu en dernier (ou pas du tout). Il n'y a pas de raison, a priori, qu'un débutant ait plus de mal avec la syntaxe d'une fonction lambda qu'une fonction normale, les limites d'un tableau, l'utilisation de code style C, etc. Si on présente à un débutant la seconde syntaxe avant la première, est-ce qu'il aura plus de mal à l'utiliser (et surtout à l'utiliser correctement)

Je ne crois pas. On verra cela sur le long terme

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 19:52:09

Oui je suis d'accord là-dessus, mais d'un côté, il faut quand même connaître les itérateurs et les fonctions lamdas, et oui je sais que c'est pas forcément "difficile", mais on ne peut pas tout apprendre d'un coup.

Prenons un débutant qui vient de commencer et qui connaît std::string et les range-based for (d'ailleurs à propos de ton post, pas de problème de v[n] avec les range-based for). Si il a envie (ou le devoir) de réaliser un code pour compter le nombre d'occurrences d'un caractère dans une chaîne, va-t-on vraiment lui dire : "attends qu'on t'ais parlé des itérateurs, des lambdas, des templates, puis apprends la liste des fonctions de la STL pour voir si une fonction peut t'être nécessaire, et peut-être là tu pourras résoudre cet exercice" ?

Je trouve ça presque absurde, parce que bien qu'un simple std::count_if ne soit pas forcément compliqué, ça demande bien plus de connaissances, et quand on débute, on a envie de tout de suite pratiquer (oui j'ai vécu ça, et je le vis encore si j'ose dire).

Je veux bien que réécrire tout un code qui pourrait être remplacé par std::search ou std::next_permutation, c'est un peu absurde car on réinvente la roue. Mais utiliser un range-based for au lieu d'un std::count_if (auquel j'avais pas pensé non plus) n'est pas une réelle infamie pour débuter à mon avis.

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 20:24:43

Non, pas une infamie bien sur, je plaisantais. Mais la façon dont on enseigne les choses influencera la façon de penser. Si on veut qu'un dev C++ pense en premier a utiliser count_if au lieu de for dans un vrai code C++ IRL, il faut lui enseigner en premier.

De même, notre façon de penser influence comment on va percevoir ce qui est difficile ou pas. Tu parles d'itérateurs et de template, mais si tu dis à un débutant qui n'a jamais vu mon code qu'il doit connaître ces deux choses avant d'utiliser count_if, il va te demander - à juste raison - où tu vois des itérateurs et des tempales dans ce code.

C'est un peu comme si tu disais que l'on ne pouvait pas utiliser std::cout avant de connaître la POO (puisque c'est un objet std::ostream). Ou que tu ne peux pas utiliser std::string avant de connaître les templates (puisque c'est un std::basic_string<char>)

C'est pareil pour begin et end. Cela représente le début et la fin d'une collection, peut importe les types réels manipulés derrière cela (dans un premier temps).

Je pense que c'est justement le challenge d'un enseignement "moderne" du C++ : ne pas simplement ajouter les nouvelles syntaxes du C++11/14/17 à un cours existant, mais remettre à plat ce que l'on veut que le futur développeur sache faire.

-
Edité par gbdivers 9 juin 2015 à 20:28:19

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 20:51:50

Oui, ma phrase est exagérée bien entendu, on a pas besoin de savoir ce qu'est vraiment un itérateur ou une fonction template, mais je disais ça dans le sens où je comprenais pourquoi l'utilisation d'un std::count_if peut paraître plus compliqué qu'un range-based for pour un débutant qui veut se lancer tout de suite. ^^

Mais le truc c'est surtout qu'il faut prendre l'habitude de fouiller parmi les fonctions de la STL, ce qui ne vient peut-être pas tout de suite à l'idée des débutants. Même avec un enseignement "moderne", ce n'est pas un prof efficace qui va nous faire connaître la liste de toutes les fonctions en 2 ou 3 cours.

D'ailleurs des profs efficaces et modernes, ça existe en fait ? ^^

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 20:57:21

Olybri a écrit:

D'ailleurs des profs efficaces et modernes, ça existe en fait ? ^^

Oui, mais pas en France. (mode bashing gratuit) :D

Et pour ce qui est de connaître les fonctions de la STL, je suis d'accord avec toi. J'ai même tendance à croire que c'est quelque chose qui est difficile de faire dans un cours (un cours pour orienter l'exploration de la STL, cela pourrait fonctionner. Mais un cours qui fait simplement le listing de chaque fonction, je crois que cela n'apporte rien de plus que lire la doc)

-
Edité par gbdivers 9 juin 2015 à 21:00:11

  • Partager sur Facebook
  • Partager sur Twitter
9 juin 2015 à 21:11:41

gbdivers a écrit:

Olybri a écrit:

D'ailleurs des profs efficaces et modernes, ça existe en fait ? ^^

Oui, mais pas en France. (mode bashing gratuit) :D

Bon, bah je verrai ce qu'il en est dans mon pays. ^^ J'ai eu jusqu'à maintenant un seul prof de programmation (en Java), et bien que je ne connaisse que peu Java, il me déçoit souvent (bon ok ça va, il comprend quand je le corrige). Bref, j'espère mieux pour mes éventuelles futures études.
  • Partager sur Facebook
  • Partager sur Twitter
8 janvier 2021 à 10:36:22 - Message modéré pour le motif suivant : Message complètement hors sujet


8 janvier 2021 à 13:42:39

Bonjour,

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération

Je ferme ce sujet. En cas de désaccord, me contacter par MP.

  • Partager sur Facebook
  • Partager sur Twitter
Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL