Coding since 11yo, that makes it over 30 years now ~~~
Have a PhD in Comp Sci ~~~
Love to go on bike tours ~~~
I try to stay as generalist as I can in this crazy wide place coding is at now.
Here's a C implementation that does a pretty good job at being as lazy as possible (which is what I always aspire to, even if it ends up being a lot of work to get to be lazy)
It updates the string in-place, passing through only once if nothing is to be done, or if its original guess of the final case was right. Otherwise, it passes through again only up to the last char it guessed wrong on.
Worst case, it iterates the string twice (minus one last character on the second pass), but the typical case is more like a single pass.
In C for old-times sake, and because if you're bothering to do this sort of thing at all it'd better be in a performant language just to make any of it worth the effort.
#include <stdio.h>
#include <string.h>
#define DEB(...) __VA_ARGS__
#define ascii_A 65
#define ascii_Z 90
#define ascii_case_bitmask 0x20
#define isUpperCase(___c) (((___c) & ascii_case_bitmask) == 0)
#define toggleCase(___c) ((___c) ^= ascii_case_bitmask)
voidconvertToPopularCase(char*s){intstat_toggleCount=0,stat_stringLength=(int)strlen(s);printf(">>> %s\n",s);intlastWrongIndex=-1,upperCount=0,lowerCount=0;charupperFTW=0;for(inti=0;s[i];i++){constcharc=s[i],upperC=c&~ascii_case_bitmask,isUpper=isUpperCase(c);if(upperC<ascii_A||upperC>ascii_Z)continue;// non-letters are ignoredupperCount+=isUpper;lowerCount+=1-isUpper;if(upperFTW!=upperCount>lowerCount){lastWrongIndex=i-1;upperFTW=!upperFTW;}if(isUpper!=upperFTW){toggleCase(s[i]);// toggle case of char in stringstat_toggleCount++;}}for(inti=0;i<=lastWrongIndex;i++){constcharc=s[i],upperC=c&~ascii_case_bitmask,isUpper=isUpperCase(c);if(upperC<ascii_A||upperC>ascii_Z)continue;if(isUpper!=upperFTW){toggleCase(s[i]);// toggle case of char in stringstat_toggleCount++;}}printf(" << %s\n (Length: %d, chars toggled: %d, total string passes including cleanup: %f\n\n",s,stat_stringLength,stat_toggleCount,(stat_stringLength+(lastWrongIndex+1))/(float)stat_stringLength);}intmain(){chartestStrings[][100]={"Following examples should be uppercase>>>","CODE","CODe","cODE","A MoNkEy","123456789 CODE","four - FIVEE + four - FIVEE","four + fivee - FOUR - SIXXXX","Following examples should be lowercase>>>","code","COde","Code","coDE","codE","MoNkEy","123456789 code","123456789 coDE","four + fivee - FOUR - FIVEE",};for(inti=0,N=sizeof(testStrings)/sizeof(*testStrings);i<N;i++){convertToPopularCase(testStrings[i]);}return0;}
Output:
(a "total string passes including cleanup" of 1 is where the string was just passed over once)
>>> Following examples should be uppercase>>>
<< following examples should be uppercase>>>
(Length: 41, chars toggled: 1, total string passes including cleanup: 1.024390
>>> CODE
<< CODE
(Length: 4, chars toggled: 0, total string passes including cleanup: 1.000000
>>> CODe
<< CODE
(Length: 4, chars toggled: 1, total string passes including cleanup: 1.000000
>>> cODE
<< CODE
(Length: 4, chars toggled: 3, total string passes including cleanup: 1.500000
>>> A MoNkEy
<< A MONKEY
(Length: 8, chars toggled: 3, total string passes including cleanup: 1.000000
>>> 123456789 CODE
<< 123456789 CODE
(Length: 14, chars toggled: 0, total string passes including cleanup: 1.714286
>>> four - FIVEE + four - FIVEE
<< FOUR - FIVEE + FOUR - FIVEE
(Length: 27, chars toggled: 22, total string passes including cleanup: 1.925926
>>> four + fivee - FOUR - SIXXXX
<< FOUR + FIVEE - FOUR - SIXXXX
(Length: 28, chars toggled: 27, total string passes including cleanup: 1.964286
>>> Following examples should be lowercase>>>
<< following examples should be lowercase>>>
(Length: 41, chars toggled: 1, total string passes including cleanup: 1.024390
>>> code
<< code
(Length: 4, chars toggled: 0, total string passes including cleanup: 1.000000
>>> COde
<< code
(Length: 4, chars toggled: 4, total string passes including cleanup: 1.750000
>>> Code
<< code
(Length: 4, chars toggled: 1, total string passes including cleanup: 1.250000
>>> coDE
<< code
(Length: 4, chars toggled: 2, total string passes including cleanup: 1.000000
>>> codE
<< code
(Length: 4, chars toggled: 1, total string passes including cleanup: 1.000000
>>> MoNkEy
<< monkey
(Length: 6, chars toggled: 3, total string passes including cleanup: 1.833333
>>> 123456789 code
<< 123456789 code
(Length: 14, chars toggled: 0, total string passes including cleanup: 1.000000
>>> 123456789 coDE
<< 123456789 code
(Length: 14, chars toggled: 2, total string passes including cleanup: 1.000000
>>> four + fivee - FOUR - FIVEE
<< four + fivee - four - fivee
(Length: 27, chars toggled: 9, total string passes including cleanup: 1.000000
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Here's a C implementation that does a pretty good job at being as lazy as possible (which is what I always aspire to, even if it ends up being a lot of work to get to be lazy)
It updates the string in-place, passing through only once if nothing is to be done, or if its original guess of the final case was right. Otherwise, it passes through again only up to the last char it guessed wrong on.
Worst case, it iterates the string twice (minus one last character on the second pass), but the typical case is more like a single pass.
In C for old-times sake, and because if you're bothering to do this sort of thing at all it'd better be in a performant language just to make any of it worth the effort.
Output:
(a "total string passes including cleanup" of 1 is where the string was just passed over once)