可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Let's say that we have an array with n elements (n > 0).
We would like to output a list of those elements, with a separator between them.
A common approach to this problem is:
foreach item
(
output item
output separator
)
trim last separator
But it seems a bit messy to have to do that.
Another approach would be:
check that there is at least one element
loop
(
output element
next element, or break if no more elements
output separator
)
But I am not sure that it will always work.
Do you see other clever ways to do that, for example in C, C++?
回答1:
char *sep = "";
for (i = 0; i < size; ++i) {
printf("%s%s", sep, item[i]);
sep = ", ";
}
回答2:
for (i = 0; i < n; ++i) switch(i) {
default: output_separator();
case 0: output_item(i);
}
or variations on this. I can't really think of how else not to repeat output_item(i)
.
回答3:
Sometimes:
output item 0
for item 1 to n
{
output separator
output item
}
is shorter.
回答4:
As it is tagged as language-agnostic I think it's important to point out, that some languages have built-in features to spare you from even thinking about this problem. Take this python code for example:
>>> print string.join(['list', 'of', 'some', 'words'], ', ')
list, of, some, words
回答5:
A possible C++ solution:
http://groups.google.com/group/comp.lang.c++/msg/a746a588cedfa44b
Summary: write an infix_ostream_iterator
, which is basically the same as ostream_iterator
except that the "separator" parameter really is a separator, not a suffix to every item. Usage would then be:
std::copy(first, last, infix_ostream_iterator<ItemType>(output, separator));
回答6:
For better or worse, I use counted loops, with
for (i = 0; i < num_items; i++){
if (i > 0) output separator;
output item[i];
}
I'm sure this is downvote-bait for being old fashioned, but it works.
If anybody wants to tell me it's inefficient, boy do I have a flame ready ;-)
回答7:
This version avoids any additional branches:
int i = 0;
goto skip_delim;
do {
put_delim();
skip_delim: put_el(i++);
} while (i < size);
(For those who are afraid of goto
, it can be written using approach from Duff's device)
回答8:
The "first check" idiom in Haskell:
intersperse :: Show a => String -> [a] -> String
intersperse _ [] = ""
intersperse s (x:xs) = show x ++ concatMap ((s ++) . show) xs
It's used like so:
*Main> intersperse "," [1,2,3]
"1,2,3"
*Main> intersperse "," [1]
"1"
*Main> intersperse ";" [1,2]
"1;2"
*Main> intersperse "," []
""
回答9:
I always use first item check idiom. Here is the code in java:
List<Object> list;
if (list.size() > 0) {
put(list.get(0));
}
for(int i = 1; i < list.size(); i++) {
putSeparator();
put(list.get(i));
}
回答10:
for i in items.length-1; do
output item; output separator
output last item
回答11:
In Common Lisp, it's bordering on simple, as long as you can hard-code the separator.
(defun return-delimited-list (list &optional stream)
(format stream "~{~A~^, ~}" list))
When called, this returns a string consisting of the elements in list
, separated by ", " (except for the last element not being followed by anything). Well, if fed an output stream, it prints it to the stream, it just so happens that 'nil' means "No stream, just return a string".