ʇolɐǝz ǝɥʇ qoq
ʇolɐǝz ǝɥʇ qoq

Reputation: 734

How to find closest vowel?

I wrote a program that lets the user input a character. If the character is a vowel, do nothing; if the character is a consonant, find the closest vowel in the alphabet. Is there any easy way to do this?

Here's what I have for now:

char input, output;
cin >> input;
if (input == 'b'){ output = 'a'; }
else if (input == 'c'){ output = 'a'; }
else if (input == 'd'){ output = 'e'; }
else if (input == 'f'){ output = 'e'; }
else if (input == 'g'){ output = 'e'; }
else if (input == 'h'){ output = 'i'; }
else if (input == 'j'){ output = 'i'; }
else if (input == 'k'){ output = 'i'; }
else if (input == 'l'){ output = 'i'; }
else if (input == 'm'){ output = 'o'; }
else if (input == 'n'){ output = 'o'; }
else if (input == 'p'){ output = 'o'; }
else if (input == 'q'){ output = 'o'; }
else if (input == 'r'){ output = 'o'; }
else if (input == 's'){ output = 'u'; }
else if (input == 't'){ output = 'u'; }
else if (input == 'v'){ output = 'u'; }
else if (input == 'w'){ output = 'u'; }
else if (input == 'x'){ output = 'u'; }
else if (input == 'y'){ output = 'u'; }
else if (input == 'z'){ output = 'u'; }

Is there a simpler way to do this?

Upvotes: 4

Views: 4175

Answers (7)

Hayden Taylor
Hayden Taylor

Reputation: 339

Here's one I made in Java, it's not assigned statically and supports lower and upper case letters.

public static char closestVowel(char character) {
    int value = (int) character;
    if(character == 'z' || character == 'Z')
        return (char) (value - 25);
    if(isVowel(character)) {
        return character;
    } else {
        return closestVowel((char) (value - 1));
    }
}

public static boolean isVowel(char character) {
    return "aeiouAEIOU".indexOf(character) >= 0;
}

Upvotes: 1

Matthias
Matthias

Reputation: 7521

This feels more generic:

  1. Get the ASCII value of the input
  2. Substract each vowels's ASCII value as its distance and store (vowel, distance) in a list
  3. Sort the list
  4. Get its first pair's key (the vowel)

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std; 

bool compare(const pair<char, int>& a, const pair<char, int>& b)
{
    return a.second < b.second;
}

int main()
{
    char vowels[] = { 'a', 'e', 'i', 'o', 'u' };
    char input;
    //std::cin >> input;
    input = 'r';
    vector<pair<char, int>> distances;
    for (char& vowel : vowels)
    {
        distances.push_back(make_pair(vowel, abs(input - vowel)));
    }
    sort(distances.begin(), distances.end(), compare);
    pair<char, int> nearest = distances.front();
    if (nearest.second > 0)
    {
        cout << nearest.first;
    }
}

Upvotes: 1

Jahid
Jahid

Reputation: 22438

It can be done like this too:

if(input>='a'&&input<='z'){
if(input<='c')output='a';
else if(input<='g')output='e';
else if(input<='l')output='i';
else if(input<='r')output='o';
else if(input<='z')output='u';
}

The first if makes sure that no input other than a~z are fed into output.

Upvotes: 4

Tony Delroy
Tony Delroy

Reputation: 106196

There are very many ways to do this, perhaps the most concise (albeit ugly) is:

const char* p = strchr(input, "bacadefegehijikilimonopoqorosutuvuwuxuyuzu");
output = (p && *p) ? p[1] : input;

This works by seeking a char* to input in that string literal, then if found it returns the following character. It won't crash for any character code 0-255, but if you input a vowel it will find it in the string and return the following consonant - if that's a problem, it's probably better to use the following...

Have two arrays - one of consonants and another of vowels, and if you find input in the former get the vowel from the same index in the latter.

Yet another way is to use a std::map:

std::map<char, char> m { { 'b', 'a' }, {'c', 'a' } etc... };
if (auto i = m.find(input))
    output = *i;
else
    output = input;

switch is a bit more verbose than the above, but will likely give the fastest performance (but do measure if you care).

Upvotes: 2

flogram_dev
flogram_dev

Reputation: 42858

You could also use an array:

const char nearestVowels[26] = "aaaeeeeiiiiioooooouuuuuyyy";
                             // abcdefghijklmnopqrstuvwxyz

Then you could simply do this:

output = nearestVowels[input - 'a'];

Upvotes: 11

Blob
Blob

Reputation: 569

Looks like you want something like this:

if (input != 'a' && input != 'e' && input != 'i' && input != 'o' && input != 'u')
{
    if ('a' <= input && input <= 'c')   { output = 'a'; }
    else if (input <= 'g')              { output = 'e'; }
    else if (input <= 'l')              { output = 'i'; }
    else if (input <= 'r')              { output = 'o'; }
    else if (input <= 'z')              { output = 'u'; }
}

Live On Coliru

Upvotes: 4

flogram_dev
flogram_dev

Reputation: 42858

switch would be simpler:

switch (input)
{
    case 'b':
    case 'c':
        output = 'a';
        break;
    case 'd':
    case 'f':
    case 'g':
        output = 'e';
        break;
    ...
    etc.
}

Upvotes: 1

Related Questions