forked from heavy3/programming-abstractions
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
192 lines (156 loc) · 5.68 KB
/
Copy pathmain.cpp
File metadata and controls
192 lines (156 loc) · 5.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
//
// main.cpp
//
// This program implements a function:
//
// int findDNAMatch(string s1, string s2, int start = 0);
//
// that returns the first position at which the DNA strand s1 can attach to
// the strand s2. As in the find method for the string class, the optional
// start parameter indicates the index position at which the search should
// start. If there is no match, findDNAMatch returns –1.
//
// I am adapting the character substitution cipher from the previous
// problem to invert the short DNA strand. The problem reduces to a
// sub-string find of the inverted DNA snippet within the longer strand.
//
// --------------------------------------------------------------------------
// Attribution: "Programming Abstractions in C++" by Eric Roberts
// Chapter 3, Exercise 20
// Stanford University, Autumn Quarter 2012
// http://web.stanford.edu/class/archive/cs/cs106b/cs106b.1136/materials/CS106BX-Reader.pdf
// --------------------------------------------------------------------------
//
// Created by Glenn Streiff on 10/12/15.
// Copyright © 2015 Glenn Streiff. All rights reserved.
//
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
// Constants and types
const string PGM_BANNER = "Find DNA Snippet Binding Position";
const string MSG_PROMPT = "Enter a DNA snippet: ";
const string ENC_OUTPUT = "The inverted strand: ";
const string KEY_OUTPUT = "Inverted key: ";
const string ALPHABET = "ACTG";
const string alphabet = "actg";
const string DNA_INVERSION_KEY = "TGAC";
const string SNIPPET = "TGC";
const string LONG_STRAND = "TAACGGTACGTC";
const size_t KEY_LENGTH = ALPHABET.length();
const string MSG_ERROR_KEY_LENGTH = "Encryption key length is incorrect.";
// Function prototypes
string encode(string plainText, string letterSubstitutionKey);
char encodeChar(char ch, string letterSubstitutionKey);
int findDNAMatch(string s1, string s2, int start = 0);
void error(string msg);
int main(int argc, const char * argv[]) {
string key;
string decodeKey;
string snippet;
string invertedSnippet;
string decodedMsg;
cout << PGM_BANNER << endl << endl;
cout << "Given the following DNA sequence: \n\t" << LONG_STRAND << endl << endl;
cout << "I'll find valid binding positions for a DNA snippet you provide.";
cout << endl << endl;
key = DNA_INVERSION_KEY;
cout << MSG_PROMPT;
snippet = SNIPPET;
cout << snippet << endl;
invertedSnippet = encode(snippet, key);
cout << ENC_OUTPUT << invertedSnippet << endl;
int pos;
pos = findDNAMatch(snippet, LONG_STRAND, pos);
if (pos == -1) {
cout << "No acceptable binding site was found for your snippet. :-(";
} else {
cout << "Your snippet can bind at (0-based) position: " << pos;
}
cout << endl;
pos = 5;
pos = findDNAMatch(snippet, LONG_STRAND, pos);
if (pos == -1) {
cout << "No acceptable binding site was found for your snippet. :-(";
} else {
cout << "Your snippet can bind at (0-based) position: " << pos;
}
cout << endl;
return 0;
}
// Function definitions
//
// Function: findDNAMatch
// Usage: int pos = findDNAMatch("TGC", "TAACGGTACGTC", 0); // returns 2
// ---------------------------------------------------------------------
// Returns the first position at which a snippet of DNA can
// bind to a larger strand of DNA according to the constraint that A may
// connect to T and C may connect to G.
// Returns -1 otherwise.
//
// An optional search position start parameter may also be passed in
// if you want to begin the search from some location beyond the default of
// 0, the start of the long strand.
//
int findDNAMatch(string s1, string s2, int start) {
string inverseS1 = encode(s1, DNA_INVERSION_KEY);
int pos = int(s2.find(inverseS1, start));
if (pos == string::npos) return -1;
return pos;
}
//
// Function: encode
// Usage: string secret = encode("plain text", "QWERTYUIOPASDFGHJKLZXCVBNM");
// --------------------------------------------------------------------------
// Returns a string that encodes the input message with a 26-character
// letter-substitution cipher key.
//
// Calls error() if key length is inadequate.
//
string encode(string plainText, string key) {
string result;
if (key.length() != KEY_LENGTH) error(MSG_ERROR_KEY_LENGTH);
for (int i = 0; i < plainText.length(); i++) {
result += char(encodeChar(plainText[i], key));
}
return result;
}
//
// Function: encodeChar
// Usage: char secretCh = encodeChar('a', QWERTYUIOPASDFGHJKLZXCVBNM);
// -------------------------------------------------------------------
// Encodes a character using a simple letter substitution cipher key.
// The offset of the charactert from the beginning of the alphabet is
// used as an index into a 26-character long key string. The looked
// up value is returned as the encrypted value for the character.
//
char encodeChar(char ch, string letterSubstitutionKey) {
size_t pos = string::npos;
char ech;
//
// Find canonical position of unencoded character in alphabet.
//
if (toupper(ch) == ch) {
pos = ALPHABET.find(ch);
} else if (tolower(ch) == ch ) {
pos = alphabet.find(ch);
}
if (pos == string::npos) {
ech = ch;
} else {
ech = letterSubstitutionKey[pos];
}
return ech;
}
//
// Function: error
// Usage: error("shut 'er down, clancy. she's pumping mud!");
// ----------------------------------------------------------
// Writes message to error console and exits program with EXIT_FAILURE
// constant defined in <cstdlib>.
//
void error(string msg) {
cerr << msg << endl;
exit(EXIT_FAILURE);
}