From e6819292b0d0a45a5d3f74af9ef320e544f42c82 Mon Sep 17 00:00:00 2001 From: zlg Date: Sun, 5 May 2013 00:54:37 -0500 Subject: Solve Exercise 4-1: strrindex() --- ch4/4-01_strrindex.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 ch4/4-01_strrindex.c (limited to 'ch4') diff --git a/ch4/4-01_strrindex.c b/ch4/4-01_strrindex.c new file mode 100644 index 0000000..b6400c4 --- /dev/null +++ b/ch4/4-01_strrindex.c @@ -0,0 +1,87 @@ +#include +#include + +/* The C Programming Language: 2nd Edition + * + * Exercise 4-1: Write the function strrindex(s, t), which returns the position + * of the /rightmost/ occurrence of 't' in 's', or -1 if there is none. + * + * Answer: The directions are unclear. Is it asking for the rightmost index of + * the first result from the beginning of the string, or the first index of the + * first occurrence from the end of the string? I will assume the leftmost + * index of the first occurrence from the end of the string, since it seems + * more difficult and relevant. + * + * This exercise was made simpler by remembering the work we did in Chapter 3. + * Specifically, itoa2. We made a reverse(s) function which reverses strings. + * If we reverse our two strings, we can pass them to strindex(), do a little + * math, and get the rightmost equivalent, all without copying and modifying + * another function! This strengthens the concept of writing functions that + * don't need to be fully understood in order to use or expand on their + * functionality. + * + * In this instance, I reversed strindex's behavior without needing to know + * anything beyond the concept of what strings are. + * + * (For the record I understand how strindex works :P) + */ + +#define MAXLINE 1000 + +void reverse(char s[]) { + int c, i, j; + + for (i = 0, j = strlen(s)-1; i < j; i++, j--) { + c = s[i]; + s[i] = s[j]; + s[j] = c; + } +} + +int strindex(char s[], char t[]) { + int i, j, k; + + for (i = 0; s[i] != '\0'; i++) { + for (j = i, k = 0; t[k] != '\0' && s[j] == t[k]; j++, k++) { + } + if (k > 0 && t[k] == '\0') { + return i; + } + } + return -1; +} + +int strrindex(char s[], char t[]) { + /* Instead of starting at the end and going back, let's be super lazy + * and just reverse it, call our buddy strindex, and reverse the + * strings again. + */ + reverse(s); + reverse(t); + /* We add strlen(t) to point to the first index of t when it's + * reversed again */ + int o = strindex(s, t) + strlen(t); + reverse(s); + reverse(t); + + // Be sure to return the correct offset with some math :3 + return (strlen(s) - o); +} + +int main() { + char haystack[MAXLINE] = "charred and burned, ouch! My stomach churned... I hope I'll be okay!"; + char needle[MAXLINE] = "ned"; + int pos = strrindex(haystack, needle); + int i = 0; + + /* This is mostly just to provide a handy visual aid */ + printf("The phrase %s's rightmost occurrence is %d:\n", needle, pos); + printf("%s\n", haystack); + for (i = 0; i < pos; i++) { + putchar(' '); + } + for (i = 0; i < strlen(needle); i++) { + putchar('^'); + } + printf("\n"); +} -- cgit v1.2.3-54-g00ecf td>-4/+8 2019-04-30Release version 0.3 beta 4zlg4-42/+100 2019-04-29README.md: Clarify a few detailszlg1-4/+2 2019-04-29setup.py: Remove obsolete informationzlg1-1/+0 2019-01-03vgstash: Add "notes" filter to schemazlg1-1/+2 2018-11-21Prepare for distributionzlg2-1/+3 2018-10-22vgstash: let backlog filter ignore unbeatable gameszlg1-1/+1 2018-10-18Bump to 0.3beta2 for PyPIzlg1-3/+3 2018-10-18vgstash.DB.__init__: fix error output formattingzlg1-1/+1 2018-10-18README: fix inline <code> formattingzlg1-3/+4 2018-10-18cli: show msg if game to be deleted is not in DBzlg2-2/+12 2018-10-18README: expand on usage, cover shell quotingzlg1-7/+99 2018-10-18cli: Tell the user when a game lacks noteszlg2-3/+15 2018-10-18Catch when an invalid list filter is passedzlg4-3/+24 2018-10-12cli: Add zero-game import/export messageszlg2-11/+18 2018-10-10Bump to 0.3beta1 for PyPIzlg1-1/+1 2018-10-10Move tests and data to dedicated directoryzlg7-10/+26 2018-10-10cli: Add "export" commandzlg2-5/+54 2018-10-10cli: Add "import" commandzlg5-1/+76 2018-10-09Bump to 0.3alpha6 for PyPIzlg1-1/+1 2018-10-09cli: Add "notes" commandzlg2-4/+74 2018-10-09update_game: ensure notes are also savedzlg1-2/+2 2018-10-09cli: add 'update' commandzlg3-20/+92 2018-10-06cli: Add "delete" commandzlg2-0/+19 2018-10-06Remove ID field from DBzlg3-38/+46 2018-10-06cli: change "Status" heading to "Progress"zlg2-36/+40 2018-09-29Bump to 0.3alpha5 for PyPIzlg1-1/+1 2018-09-29cli: Add pretty printing to 'list' commandzlg3-17/+107 2018-09-08setup.py: Bump to alpha4 for PyPIzlg1-1/+1 2018-09-08cli: add '--raw' option to list commandzlg2-9/+45 2018-09-08Add remaining filters to vgstash packagezlg1-2/+11 2018-09-04Update LICENSE to match setup.pyzlg1-80/+67 2018-09-03Branch off from master with pytest, tox, clickzlg16-778/+779 2018-03-18Flesh out filter types and ownership statuszlg3-82/+144 2018-03-18README.mdown: break line correctlyzlg1-1/+1 2018-03-18add 'playlog' list filterzlg2-2/+9 2018-03-13Update helpers a bitzlg1-2/+9 2018-03-13Make VGSTASH_DB_LOCATION point to a filezlg2-21/+20 2016-11-18Remove settings from helpers.shZe Libertine Gamer1-5/+0 2016-11-15Correct phrasing in README.Ze Libertine Gamer1-4/+4 2016-11-13DerpZe Libertine Gamer1-0/+1 2016-11-03Improve error handling in shell scriptsZe Libertine Gamer4-3/+23 2016-10-24Correct run_again, add recursionZe Libertine Gamer1-0/+4 2016-10-21Add quotes to correct behavior for arglistZe Libertine Gamer1-1/+1 2016-10-14updater.sh: add recursion, error handlingZe Libertine Gamer1-43/+101 2016-10-14Correct pipe-handling behaviorZe Libertine Gamer1-1/+9 2016-10-12Clarify a method to move between platformsZe Libertine Gamer1-2/+5