我需要查找并计算字符串中可以找到多少个字符。我把字符分成了chars1 [a:m]和chars2 [n:z],并且有两个计数器。
输出应为0/14,但它是0/1。我认为它只检查是否包含一个且只有一个项目,然后退出循环。是这样的吗?
这是代码。
string_1 = "aaabbbbhaijjjm"
def error_printer(s):
chars1 = "abcdefghijklm"
chars2 = "nopqrstuvwxyz"
counter1 = 0
counter2 = 0
if ((c in s) for c in chars1):
counter1 += 1
elif ((c in s) for c in chars2):
counter2 += 1
print(str(counter2) + "/" + str(counter1))
error_printer(string_1)
答案 0 :(得分:7)
chars1
chars2
/ s
中的字符数
这是有道理的,因为你以if
条件增加。由于循环中的if
不是,因此您可以将其递增一次。
现在我们可以将展开到for
循环。这将解决问题的一部分,生成0/6
:
for c in chars1:
if c in s:
counter1 += 1
for c in chars2:
if c in s:
counter2 += 1
然而,这仍然不会非常有效:它需要 O(n)最坏的情况来检查字符是否在字符串中。您可以首先使用字符串中的字符构造set
,然后执行查找(通常情况下通常为 O(1):
def error_printer(s):
sset = set(s)
chars1 = "abcdefghijklm"
chars2 = "nopqrstuvwxyz"
counter1 = 0
counter2 = 0
for c in chars1:
if c in sset:
counter1 += 1
for c in chars2:
if c in sset:
counter2 += 1
print(str(counter2) + "/" + str(counter1))
现在我们已经提高了效率,但它仍然不是很优雅:它需要大量的代码,而且还必须检查代码以了解它的作用。我们可以使用sum(..)
构造来计算满足某个约束的元素数量,如:
def error_printer(s):
sset = set(s)
chars1 = "abcdefghijklm"
chars2 = "nopqrstuvwxyz"
counter1 = sum(c in sset for c in chars1)
counter2 = sum(c in sset for c in chars2)
print(str(counter2) + "/" + str(counter1))
这会产生0/6
,因为[A-M]
范围内的s
范围内有六个字符,而[N-Z]
范围内的s
范围内有0个字符。
s
/ char1
char2
中的字符数
根据问题正文,您希望计算s
中出现在两个不同范围内的字符数。
另一个相关问题是计算char1
/ char2
中出现的字符数。在这种情况下,我们只需交换循环:
def error_printer(s):
chars1 = set("abcdefghijklm")
chars2 = set("nopqrstuvwxyz")
counter1 = sum(c in chars1 for c in s)
counter2 = sum(c in chars2 for c in s)
print(str(counter2) + "/" + str(counter1))
这会产生0/14
,因为s
范围内有14个字符出现在[A-M]
范围内(如果'a'
在s
中出现两次,那么我们会计算两次),s
中没有任何字符出现在[N-Z]
范围内。
由于我们使用范围,我们可以使用比较而不是元素检查,并使其运行两次比较检查,例如:
def error_printer(s):
counter1 = sum('a' <= c <= 'm' for c in s)
counter2 = sum('n' <= c <= 'z' for c in s)
print(str(counter2) + "/" + str(counter1))
答案 1 :(得分:6)
尝试使用if条件递增,在s上使用单个循环。
public class MainActivity extends AppCompatActivity {
private FragmentManager manger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<Chat> chatList = new ArrayList<>();
chatList.add(new Chat("send post card", " ", R.drawable.sentpostcard));
chatList.add(new Chat("send greeting card", "happy holiday", R.drawable.greetingcard));
chatList.add(new Chat("special designs", "choose a card", R.drawable.special));
ChatAdapter adapter = new ChatAdapter(chatList);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.chatList);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
// 1
public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder>{
// 7
private ArrayList<Chat> chats;
// 8
public ChatAdapter(ArrayList<Chat> chats) {
this.chats = chats;
}
// 10
@Override
public ChatViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = getLayoutInflater();
View v = inflater.inflate(R.layout.chat_list_item, parent, false); // false == do not attach to root
return new ChatViewHolder(v);
}
// 11
@Override
public void onBindViewHolder(ChatViewHolder holder, int position) {
holder.bind( chats.get(position) );
}
// 9
@Override
public int getItemCount() {
return chats.size();
}
// 2
public class ChatViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
//4
private TextView textName, textChat;
private ImageView imageChat;
//we need to remember a chat for each view holder and we bind the chat object using the bind function
//this will be useful later in the onClick Listener
private Chat c;
// view is the layout view ==> it contains all of the view in the layout file
// 3
public ChatViewHolder(View itemView) {
super(itemView);
// 5
textName = (TextView) itemView.findViewById(R.id.textName);
textChat = (TextView) itemView.findViewById(R.id.textChat);
imageChat = (ImageView) itemView.findViewById(R.id.imageChat);
// 12
itemView.setOnClickListener(this);
}
// 6
public void bind(Chat chat){
c = chat;
textName.setText(chat.getName());
textChat.setText(chat.getText());
imageChat.setImageResource(chat.getImage());
}
@Override
public void onClick(View v) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new FragA()).commit();
}
}
}
}
答案 2 :(得分:4)
for循环的替代方法:
string_1 = "aaabbbbhaijjjm"
def error_printer(s):
chars1 = "abcdefghijklm"
chars2 = "nopqrstuvwxyz"
counter1 = sum(s.count(c) for c in chars1)
counter2 = sum(s.count(c) for c in chars2)
print(str(counter2) + "/" + str(counter1))
error_printer(string_1)
如果您计算"a"
,"b"
,"c"
...在字符串输入中显示的次数,那么您可以将其总结。
它仍然效率低下,但利用string.count
和sum
函数,使其更容易阅读和理解正在发生的事情。
答案 3 :(得分:2)
两个计数器的s
单个for循环:
string_1 = "aaabbbbhaijjjm"
def error_printer(s):
chars1 = "abcdefghijklm"
chars2 = "nopqrstuvwxyz"
counter1 = 0
counter2 = 0
for c in s:
if c in chars1:
counter1 += 1
if c in chars2:
counter2 += 1
print(str(counter2) + "/" + str(counter1))
error_printer(string_1)
答案 4 :(得分:2)
您可以将collections.Counter
与sum
结合使用:
from collections import Counter
def error_printer(s):
cnts = Counter(s)
chars1 = "abcdefghijklm"
chars2 = "nopqrstuvwxyz"
print(sum(cnts[c] for c in chars2), '/', sum(cnts[c] for c in chars1))
>>> error_printer("aaabbbbhaijjjm")
0 / 14
答案 5 :(得分:1)
正如已经建议的那样,for循环是可行的方法。您使用生成器表达式作为if语句的布尔值,该语句只运行一次。第一个表达式被评估True
,但这不会使它多次运行包含的代码。但是,由于第一个if
确实运行了,elif
甚至从未评估其条件。这就是你想要循环的原因,但你不应该遍历char1和char2,你想循环遍历s:
for c in s:
if c in char1:
counter1 += 1
if c in char2:
counter2 += 1
print(str(counter2) + "/" + str(counter1))
这指出了一些更加流畅的方法,首先使用c in charX
作为迭代器:
for c in s:
counter1 += c in char1
counter2 += c in char2
现在这已经变得不那么清楚,但我们可以通过添加第二个for循环来使它更清晰:
char = [‘abcdefghijklm’,’nopqrstuvwxyz’]
counter = [0,0]
for c in s:
for i in [0,1]:
counter[i] += c in char[i]
这可能有点推动它,但我希望它能帮助你看到如何在python中重新排列这些东西!
(根据以下评论进行编辑)